Changeset 256820 in webkit
- Timestamp:
- Feb 17, 2020, 10:32:42 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 38 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r256802 r256820 1 2020-02-17 Chris Dumez <cdumez@apple.com> 2 3 [WK2][Cocoa] Implement in-WebProcess cookie cache to avoid sync IPC for document.cookie in most cases 4 https://bugs.webkit.org/show_bug.cgi?id=207593 5 <rdar://problem/56027027> 6 7 Reviewed by Antti Koivisto. 8 9 Add layout test coverage. 10 11 * http/tests/cookies/document-cookie-after-showModalDialog-expected.txt: Added. 12 * http/tests/cookies/document-cookie-after-showModalDialog.html: Added. 13 * http/tests/cookies/document-cookie-during-iframe-parsing-expected.txt: Added. 14 * http/tests/cookies/document-cookie-during-iframe-parsing.html: Added. 15 * http/tests/cookies/resources/close-modal-dialog.html: Added. 16 * http/tests/cookies/resources/document-cookie-during-iframe-parsing-iframe.html: Added. 17 * http/tests/cookies/resources/set-cookie-and-serve.php: Added. 18 1 19 2020-02-17 Ryan Haddad <ryanhaddad@apple.com> 2 20 -
trunk/Source/WTF/ChangeLog
r256806 r256820 1 2020-02-17 Chris Dumez <cdumez@apple.com> 2 3 [WK2][Cocoa] Implement in-WebProcess cookie cache to avoid sync IPC for document.cookie in most cases 4 https://bugs.webkit.org/show_bug.cgi?id=207593 5 <rdar://problem/56027027> 6 7 Reviewed by Antti Koivisto. 8 9 Add build time flags for new feature. 10 11 * wtf/PlatformEnable.h: 12 * wtf/PlatformHave.h: 13 1 14 2020-02-17 Tim Horton <timothy_horton@apple.com> 2 15 -
trunk/Source/WTF/wtf/HashSet.h
r247767 r256820 113 113 template<typename IteratorType> 114 114 bool add(IteratorType begin, IteratorType end); 115 template<typename IteratorType> 116 bool remove(IteratorType begin, IteratorType end); 115 117 116 118 bool remove(const ValueType&); … … 272 274 273 275 template<typename T, typename U, typename V> 276 template<typename IteratorType> 277 inline bool HashSet<T, U, V>::remove(IteratorType begin, IteratorType end) 278 { 279 bool changed = false; 280 for (IteratorType iter = begin; iter != end; ++iter) 281 changed |= remove(*iter); 282 return changed; 283 } 284 285 template<typename T, typename U, typename V> 274 286 inline bool HashSet<T, U, V>::remove(iterator it) 275 287 { -
trunk/Source/WTF/wtf/PlatformHave.h
r256806 r256820 562 562 #endif 563 563 564 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101600) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000) 565 #define HAVE_COOKIE_CHANGE_LISTENER_API 1 566 #endif 567 564 568 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || PLATFORM(IOS_FAMILY) 565 569 #define HAVE_DATA_PROTECTION_KEYCHAIN 1 -
trunk/Source/WebCore/ChangeLog
r256808 r256820 1 2020-02-17 Chris Dumez <cdumez@apple.com> 2 3 [WK2][Cocoa] Implement in-WebProcess cookie cache to avoid sync IPC for document.cookie in most cases 4 https://bugs.webkit.org/show_bug.cgi?id=207593 5 <rdar://problem/56027027> 6 7 Reviewed by Antti Koivisto. 8 9 Implement in-WebProcess DOM cookie cache for serving `document.cookie` requests from JavaScript. 10 11 The first time document.cookie is called for a given host, the WebProcess will pull in all the 12 non-HTTPOnly cookies for that host from the NetworkProcess (still via sync IPC) and store them 13 in an in-memory cookie store. Later document.cookie calls for this host from this WebProcess 14 will then leverage the in-memory cookie store and avoid doing a sync IPC to the NetworkProcess 15 entirely. 16 17 To maintain the in-process cookie store up-to-date, the WebProcess subscribe for cookie-change 18 notifications from the NetworkProcess, only for the hosts it is interested in. 19 20 If the page's JavaScript sets a cookie by setting document.cookie, we will not invalidate the 21 cache for performance reasons. Instead, we set the cookie in our in-memory cookie before 22 sending the new cookie to the NetworkProcess. 23 24 For compatibility reasons, any sync IPC to a given host will currently invalidate the cookie 25 cache for this host. This is because this synchronous load may cause cookies to get set 26 synchronously and the page could access document.cookie right after the sync XHR. This behavior 27 is covered by the following existing test: 28 - http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html 29 30 Another limitation of the current implementation of the cookie cache is that it is currently 31 only leveraged for first party content. This is suboptimal and could be improved in a later 32 iteration. However, the default behavior in Safari is that third-party iframes do not have 33 cookie access unless they request it using the storage access API. We also currently have 34 a limit of 5 hosts with cached cookies per WebProcess. 35 36 Tests: http/tests/cookies/document-cookie-after-showModalDialog.html 37 http/tests/cookies/document-cookie-during-iframe-parsing.html 38 39 * dom/Document.cpp: 40 (WebCore::Document::didLoadResourceSynchronously): 41 * dom/Document.h: 42 * dom/ScriptExecutionContext.cpp: 43 (WebCore::ScriptExecutionContext::didLoadResourceSynchronously): 44 * dom/ScriptExecutionContext.h: 45 * loader/CookieJar.h: 46 * loader/ThreadableLoader.cpp: 47 (WebCore::ThreadableLoader::loadResourceSynchronously): 48 * page/MemoryRelease.cpp: 49 (WebCore::releaseCriticalMemory): 50 * page/Settings.yaml: 51 * platform/network/NetworkStorageSession.h: 52 (WebCore::CookieChangeObserver::~CookieChangeObserver): 53 * platform/network/cf/NetworkStorageSessionCFNet.cpp: 54 (WebCore::NetworkStorageSession::NetworkStorageSession): 55 (WebCore::NetworkStorageSession::cookieStorage const): 56 * platform/network/cocoa/NetworkStorageSessionCocoa.mm: 57 (WebCore::NetworkStorageSession::~NetworkStorageSession): 58 (WebCore::NetworkStorageSession::setCookie): 59 (WebCore::NetworkStorageSession::setCookies): 60 (WebCore::NetworkStorageSession::deleteCookie): 61 (WebCore::nsCookiesToCookieVector): 62 (WebCore::NetworkStorageSession::nsCookieStorage const): 63 (WebCore::createPrivateStorageSession): 64 (WebCore::NetworkStorageSession::httpCookies const): 65 (WebCore::NetworkStorageSession::deleteHTTPCookie const): 66 (WebCore::NetworkStorageSession::setHTTPCookiesForURL const): 67 (WebCore::NetworkStorageSession::httpCookiesForURL const): 68 (WebCore::filterCookies): 69 (WebCore::NetworkStorageSession::cookiesForURL const): 70 (WebCore::NetworkStorageSession::cookiesForSession const): 71 (WebCore::NetworkStorageSession::cookiesForDOM const): 72 (WebCore::NetworkStorageSession::cookieRequestHeaderFieldValue const): 73 (WebCore::NetworkStorageSession::setCookiesFromDOM const): 74 (WebCore::NetworkStorageSession::getRawCookies const): 75 (WebCore::NetworkStorageSession::deleteCookiesForHostnames): 76 (WebCore::NetworkStorageSession::registerCookieChangeListenersIfNecessary): 77 (WebCore::NetworkStorageSession::unregisterCookieChangeListenersIfNecessary): 78 (WebCore::NetworkStorageSession::startListeningForCookieChangeNotifications): 79 (WebCore::NetworkStorageSession::stopListeningForCookieChangeNotifications): 80 (WebCore::NetworkStorageSession::domCookiesForHost): 81 (WebCore::NetworkStorageSession::supportsCookieChangeListenerAPI const): 82 1 83 2020-02-17 Chris Dumez <cdumez@apple.com> 2 84 -
trunk/Source/WebCore/PAL/ChangeLog
r256770 r256820 1 2020-02-17 Chris Dumez <cdumez@apple.com> 2 3 [WK2][Cocoa] Implement in-WebProcess cookie cache to avoid sync IPC for document.cookie in most cases 4 https://bugs.webkit.org/show_bug.cgi?id=207593 5 <rdar://problem/56027027> 6 7 Reviewed by Antti Koivisto. 8 9 Add new CFNetwork SPI to CFNetworkSPI.h for open source builds and for using respondsToSelector. 10 11 * pal/spi/cf/CFNetworkSPI.h: 12 1 13 2020-02-17 Peng Liu <peng.liu6@apple.com> 2 14 -
trunk/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h
r255461 r256820 392 392 @interface NSHTTPCookieStorage () 393 393 + (void)_setSharedHTTPCookieStorage:(NSHTTPCookieStorage *)storage; 394 - (void)_setSubscribedDomainsForCookieChanges:(NSSet<NSString*>* __nullable)domainList; 395 - (void)_setCookiesAddedHandler:(void(^__nullable)(NSArray<NSHTTPCookie*>* addedCookies, NSURL* __nullable urlForAddedCookies))cookiesAddedHandler onQueue:(dispatch_queue_t __nullable)queue; 396 - (void)_setCookiesDeletedHandler:(void(^__nullable)(NSArray<NSHTTPCookie*>* __nullable deletedCookies, bool deletedAllCookies))cookiesDeletedHandler onQueue:(dispatch_queue_t __nullable)queue; 397 - (NSArray* __nullable)_getCookiesForDomain:(NSString*)domain; 394 398 @end 395 399 -
trunk/Source/WebCore/dom/Document.cpp
r256786 r256820 7204 7204 } 7205 7205 7206 void Document::didLoadResourceSynchronously( )7206 void Document::didLoadResourceSynchronously(const URL& url) 7207 7207 { 7208 7208 // Synchronous resources loading can set cookies so we invalidate the cookies cache 7209 7209 // in this case, to be safe. 7210 7210 invalidateDOMCookieCache(); 7211 7212 if (auto* page = this->page()) 7213 page->cookieJar().clearCacheForHost(url.host().toString()); 7211 7214 } 7212 7215 -
trunk/Source/WebCore/dom/Document.h
r256786 r256820 1642 1642 bool isDOMCookieCacheValid() const { return m_cookieCacheExpiryTimer.isActive(); } 1643 1643 void invalidateDOMCookieCache(); 1644 void didLoadResourceSynchronously( ) final;1644 void didLoadResourceSynchronously(const URL&) final; 1645 1645 1646 1646 bool canNavigateInternal(Frame& targetFrame); -
trunk/Source/WebCore/dom/ScriptExecutionContext.cpp
r254087 r256820 219 219 } 220 220 221 void ScriptExecutionContext::didLoadResourceSynchronously( )221 void ScriptExecutionContext::didLoadResourceSynchronously(const URL&) 222 222 { 223 223 } -
trunk/Source/WebCore/dom/ScriptExecutionContext.h
r256012 r256820 153 153 void destroyedMessagePort(MessagePort&); 154 154 155 virtual void didLoadResourceSynchronously( );155 virtual void didLoadResourceSynchronously(const URL&); 156 156 157 157 void ref() { refScriptExecutionContext(); } -
trunk/Source/WebCore/loader/CookieJar.h
r250287 r256820 61 61 virtual void deleteCookie(const Document&, const URL&, const String& cookieName); 62 62 63 // Cookie Cache. 64 virtual void clearCache() { } 65 virtual void clearCacheForHost(const String&) { } 66 63 67 virtual ~CookieJar(); 64 68 protected: -
trunk/Source/WebCore/loader/ThreadableLoader.cpp
r238933 r256820 111 111 void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext& context, ResourceRequest&& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) 112 112 { 113 auto resourceURL = request.url(); 113 114 if (is<WorkerGlobalScope>(context)) 114 115 WorkerThreadableLoader::loadResourceSynchronously(downcast<WorkerGlobalScope>(context), WTFMove(request), client, options); 115 116 else 116 117 DocumentThreadableLoader::loadResourceSynchronously(downcast<Document>(context), WTFMove(request), client, options); 117 context.didLoadResourceSynchronously( );118 context.didLoadResourceSynchronously(resourceURL); 118 119 } 119 120 -
trunk/Source/WebCore/page/MemoryRelease.cpp
r255071 r256820 34 34 #include "ChromeClient.h" 35 35 #include "CommonVM.h" 36 #include "CookieJar.h" 36 37 #include "Document.h" 37 38 #include "FontCache.h" … … 100 101 CSSValuePool::singleton().drain(); 101 102 103 Page::forEachPage([](auto& page) { 104 page.cookieJar().clearCache(); 105 }); 106 102 107 for (auto& document : copyToVectorOf<RefPtr<Document>>(Document::allDocuments())) { 103 108 document->styleScope().releaseMemory(); -
trunk/Source/WebCore/page/Settings.yaml
r256808 r256820 362 362 initial: false 363 363 364 inProcessCookieCacheEnabled: 365 initial: false 366 364 367 thirdPartyIframeRedirectBlockingEnabled: 365 368 initial: true -
trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp
r254931 r256820 27 27 #include "NetworkStorageSession.h" 28 28 29 #include "Cookie.h" 29 30 #include "HTTPCookieAcceptPolicy.h" 30 31 #include "RuntimeApplicationChecks.h" … … 56 57 removeProcessPrivilege(ProcessPrivilege::CanAccessRawCookies); 57 58 } 59 60 #if !PLATFORM(COCOA) 61 Vector<Cookie> NetworkStorageSession::domCookiesForHost(const String&) 62 { 63 ASSERT_NOT_IMPLEMENTED_YET(); 64 return { }; 65 } 66 #endif // !PLATFORM(COCOA) 58 67 59 68 #if ENABLE(RESOURCE_LOAD_STATISTICS) -
trunk/Source/WebCore/platform/network/NetworkStorageSession.h
r254931 r256820 1 1 /* 2 * Copyright (C) 2012-20 18Apple Inc. All rights reserved.2 * Copyright (C) 2012-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 61 61 #if PLATFORM(COCOA) 62 62 #include "CookieStorageObserver.h" 63 OBJC_CLASS NSArray; 64 OBJC_CLASS NSHTTPCookie; 65 OBJC_CLASS NSMutableSet; 63 66 #endif 64 67 … … 80 83 enum class ShouldAskITP : bool { No, Yes }; 81 84 85 #if HAVE(COOKIE_CHANGE_LISTENER_API) 86 class CookieChangeObserver { 87 public: 88 virtual ~CookieChangeObserver() { } 89 virtual void cookiesAdded(const String& host, const Vector<WebCore::Cookie>&) = 0; 90 virtual void cookiesDeleted() = 0; 91 }; 92 #endif 93 82 94 class NetworkStorageSession { 83 95 WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED; … … 93 105 #endif 94 106 107 #if PLATFORM(COCOA) 108 WEBCORE_EXPORT ~NetworkStorageSession(); 109 #endif 110 95 111 #if PLATFORM(COCOA) || USE(CFURLCONNECTION) 96 112 WEBCORE_EXPORT static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier); 97 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, RetainPtr<CFURLStorageSessionRef>&&, RetainPtr<CFHTTPCookieStorageRef>&&); 113 enum class IsInMemoryCookieStore : bool { No, Yes }; 114 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, RetainPtr<CFURLStorageSessionRef>&&, RetainPtr<CFHTTPCookieStorageRef>&&, IsInMemoryCookieStore = IsInMemoryCookieStore::No); 98 115 WEBCORE_EXPORT explicit NetworkStorageSession(PAL::SessionID); 99 116 … … 146 163 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<FrameIdentifier>, Optional<PageIdentifier>, IncludeSecureCookies, ShouldAskITP) const; 147 164 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const CookieRequestHeaderFieldProxy&) const; 165 166 WEBCORE_EXPORT Vector<Cookie> domCookiesForHost(const String& host); 167 168 #if HAVE(COOKIE_CHANGE_LISTENER_API) 169 WEBCORE_EXPORT void startListeningForCookieChangeNotifications(CookieChangeObserver&, const String& host); 170 WEBCORE_EXPORT void stopListeningForCookieChangeNotifications(CookieChangeObserver&, const HashSet<String>& hosts); 171 WEBCORE_EXPORT bool supportsCookieChangeListenerAPI() const; 172 #endif 148 173 149 174 #if ENABLE(RESOURCE_LOAD_STATISTICS) … … 174 199 175 200 private: 201 #if PLATFORM(COCOA) 202 enum IncludeHTTPOnlyOrNot { DoNotIncludeHTTPOnly, IncludeHTTPOnly }; 203 std::pair<String, bool> cookiesForSession(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<FrameIdentifier>, Optional<PageIdentifier>, IncludeHTTPOnlyOrNot, IncludeSecureCookies, ShouldAskITP = ShouldAskITP::Yes) const; 204 NSArray *httpCookies(CFHTTPCookieStorageRef) const; 205 NSArray *httpCookiesForURL(CFHTTPCookieStorageRef, NSURL *firstParty, const Optional<SameSiteInfo>&, NSURL *) const; 206 NSArray *cookiesForURL(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<FrameIdentifier>, Optional<PageIdentifier>, ShouldAskITP) const; 207 void setHTTPCookiesForURL(CFHTTPCookieStorageRef, NSArray *cookies, NSURL *, NSURL *mainDocumentURL, const SameSiteInfo&) const; 208 void deleteHTTPCookie(CFHTTPCookieStorageRef, NSHTTPCookie *) const; 209 #endif 210 211 #if HAVE(COOKIE_CHANGE_LISTENER_API) 212 void registerCookieChangeListenersIfNecessary(); 213 void unregisterCookieChangeListenersIfNecessary(); 214 #endif 215 176 216 PAL::SessionID m_sessionID; 177 217 … … 179 219 RetainPtr<CFURLStorageSessionRef> m_platformSession; 180 220 RetainPtr<CFHTTPCookieStorageRef> m_platformCookieStorage; 221 bool m_isInMemoryCookieStore { false }; 181 222 #elif USE(SOUP) 182 223 static void cookiesDidChange(NetworkStorageSession*); … … 189 230 #else 190 231 RefPtr<NetworkingContext> m_context; 232 #endif 233 234 #if HAVE(COOKIE_CHANGE_LISTENER_API) 235 bool m_didRegisterCookieListeners { false }; 236 RetainPtr<NSMutableSet> m_subscribedDomainsForCookieChanges; 237 HashMap<String, HashSet<CookieChangeObserver*>> m_cookieChangeObservers; 191 238 #endif 192 239 -
trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
r240557 r256820 74 74 } 75 75 76 NetworkStorageSession::NetworkStorageSession(PAL::SessionID sessionID, RetainPtr<CFURLStorageSessionRef>&& platformSession, RetainPtr<CFHTTPCookieStorageRef>&& platformCookieStorage )76 NetworkStorageSession::NetworkStorageSession(PAL::SessionID sessionID, RetainPtr<CFURLStorageSessionRef>&& platformSession, RetainPtr<CFHTTPCookieStorageRef>&& platformCookieStorage, IsInMemoryCookieStore isInMemoryCookieStore) 77 77 : m_sessionID(sessionID) 78 78 , m_platformSession(WTFMove(platformSession)) 79 , m_isInMemoryCookieStore(isInMemoryCookieStore == IsInMemoryCookieStore::Yes) 79 80 { 80 ASSERT(processMayUseCookieAPI() || !platformCookieStorage );81 ASSERT(processMayUseCookieAPI() || !platformCookieStorage || m_isInMemoryCookieStore); 81 82 m_platformCookieStorage = platformCookieStorage ? WTFMove(platformCookieStorage) : cookieStorage(); 82 83 } … … 89 90 RetainPtr<CFHTTPCookieStorageRef> NetworkStorageSession::cookieStorage() const 90 91 { 91 if (!processMayUseCookieAPI() )92 if (!processMayUseCookieAPI() && !m_isInMemoryCookieStore) 92 93 return nullptr; 93 94 94 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );95 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 95 96 96 97 if (m_platformCookieStorage) -
trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
r255146 r256820 1 1 /* 2 * Copyright (C) 2015-20 18Apple Inc. All rights reserved.2 * Copyright (C) 2015-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 45 45 namespace WebCore { 46 46 47 NetworkStorageSession::~NetworkStorageSession() 48 { 49 #if HAVE(COOKIE_CHANGE_LISTENER_API) 50 unregisterCookieChangeListenersIfNecessary(); 51 #endif 52 } 53 47 54 void NetworkStorageSession::setCookie(const Cookie& cookie) 48 55 { 49 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );56 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 50 57 51 58 BEGIN_BLOCK_OBJC_EXCEPTIONS; … … 56 63 void NetworkStorageSession::setCookies(const Vector<Cookie>& cookies, const URL& url, const URL& mainDocumentURL) 57 64 { 58 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );65 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 59 66 60 67 RetainPtr<NSMutableArray> nsCookies = adoptNS([[NSMutableArray alloc] initWithCapacity:cookies.size()]); … … 69 76 void NetworkStorageSession::deleteCookie(const Cookie& cookie) 70 77 { 71 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );78 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 72 79 [nsCookieStorage() deleteCookie:(NSHTTPCookie *)cookie]; 73 80 } 74 81 75 static Vector<Cookie> nsCookiesToCookieVector(NSArray<NSHTTPCookie *> *nsCookies) 76 { 77 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); 78 82 static Vector<Cookie> nsCookiesToCookieVector(NSArray<NSHTTPCookie *> *nsCookies, const Function<bool(NSHTTPCookie *)>& filter = { }) 83 { 79 84 Vector<Cookie> cookies; 80 85 cookies.reserveInitialCapacity(nsCookies.count); 81 for (NSHTTPCookie *nsCookie in nsCookies) 82 cookies.uncheckedAppend(nsCookie); 83 86 for (NSHTTPCookie *nsCookie in nsCookies) { 87 if (!filter || filter(nsCookie)) 88 cookies.uncheckedAppend(nsCookie); 89 } 84 90 return cookies; 85 91 } … … 119 125 NSHTTPCookieStorage *NetworkStorageSession::nsCookieStorage() const 120 126 { 121 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );127 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 122 128 auto cfCookieStorage = cookieStorage(); 123 129 if (!cfCookieStorage || [NSHTTPCookieStorage sharedHTTPCookieStorage]._cookieStorage == cfCookieStorage) … … 159 165 CFURLCacheSetMemoryCapacity(cache.get(), [[NSURLCache sharedURLCache] memoryCapacity]); 160 166 161 if (!NetworkStorageSession::processMayUseCookieAPI())162 return storageSession.leakRef();163 164 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));165 166 167 auto cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, storageSession.get())); 167 168 if (!cookieStorage) … … 174 175 } 175 176 176 static NSArray *httpCookies(CFHTTPCookieStorageRef cookieStorage) 177 { 178 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); 179 if (!cookieStorage) 177 NSArray *NetworkStorageSession::httpCookies(CFHTTPCookieStorageRef cookieStorage) const 178 { 179 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 180 if (!cookieStorage) { 181 RELEASE_ASSERT(!m_isInMemoryCookieStore); 180 182 return [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; 183 } 181 184 182 185 auto cookies = adoptCF(CFHTTPCookieStorageCopyCookies(cookieStorage)); … … 184 187 } 185 188 186 static void deleteHTTPCookie(CFHTTPCookieStorageRef cookieStorage, NSHTTPCookie *cookie) 187 { 188 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );189 void NetworkStorageSession::deleteHTTPCookie(CFHTTPCookieStorageRef cookieStorage, NSHTTPCookie *cookie) const 190 { 191 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 189 192 if (!cookieStorage) { 193 RELEASE_ASSERT(!m_isInMemoryCookieStore); 190 194 [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie]; 191 195 return; … … 227 231 } 228 232 229 static void setHTTPCookiesForURL(CFHTTPCookieStorageRef cookieStorage, NSArray *cookies, NSURL *url, NSURL *mainDocumentURL, const SameSiteInfo& sameSiteInfo) 230 { 231 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );233 void NetworkStorageSession::setHTTPCookiesForURL(CFHTTPCookieStorageRef cookieStorage, NSArray *cookies, NSURL *url, NSURL *mainDocumentURL, const SameSiteInfo& sameSiteInfo) const 234 { 235 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 232 236 if (!cookieStorage) { 233 237 #if !(PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101400) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV) … … 256 260 } 257 261 258 static NSArray *httpCookiesForURL(CFHTTPCookieStorageRef cookieStorage, NSURL *firstParty, const Optional<SameSiteInfo>& sameSiteInfo, NSURL *url) 259 { 260 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); 261 if (!cookieStorage) 262 NSArray *NetworkStorageSession::httpCookiesForURL(CFHTTPCookieStorageRef cookieStorage, NSURL *firstParty, const Optional<SameSiteInfo>& sameSiteInfo, NSURL *url) const 263 { 264 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 265 if (!cookieStorage) { 266 RELEASE_ASSERT(!m_isInMemoryCookieStore); 262 267 cookieStorage = _CFHTTPCookieStorageGetDefault(kCFAllocatorDefault); 268 } 263 269 264 270 // FIXME: Stop creating a new NSHTTPCookieStorage object each time we want to query the cookie jar. 265 271 // NetworkStorageSession could instead keep a NSHTTPCookieStorage object for us. 266 272 RetainPtr<NSHTTPCookieStorage> nsCookieStorage = adoptNS([[NSHTTPCookieStorage alloc] _initWithCFHTTPCookieStorage:cookieStorage]); 267 return cookiesForURL(nsCookieStorage.get(), url, firstParty, sameSiteInfo);273 return WebCore::cookiesForURL(nsCookieStorage.get(), url, firstParty, sameSiteInfo); 268 274 } 269 275 270 276 static RetainPtr<NSArray> filterCookies(NSArray *unfilteredCookies, Optional<Seconds> cappedLifetime) 271 277 { 272 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));273 278 NSUInteger count = [unfilteredCookies count]; 274 279 RetainPtr<NSMutableArray> filteredCookies = adoptNS([[NSMutableArray alloc] initWithCapacity:count]); … … 303 308 } 304 309 305 static NSArray *cookiesForURL(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, ShouldAskITP shouldAskITP) 310 NSArray *NetworkStorageSession::cookiesForURL(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, ShouldAskITP shouldAskITP) const 306 311 { 307 312 #if ENABLE(RESOURCE_LOAD_STATISTICS) 308 if (shouldAskITP == ShouldAskITP::Yes && s ession.shouldBlockCookies(firstParty, url, frameID, pageID))313 if (shouldAskITP == ShouldAskITP::Yes && shouldBlockCookies(firstParty, url, frameID, pageID)) 309 314 return nil; 310 315 #else … … 313 318 UNUSED_PARAM(shouldAskITP); 314 319 #endif 315 return httpCookiesForURL(session.cookieStorage().get(), firstParty, sameSiteInfo, url); 316 } 317 318 enum IncludeHTTPOnlyOrNot { DoNotIncludeHTTPOnly, IncludeHTTPOnly }; 319 static std::pair<String, bool> cookiesForSession(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, IncludeHTTPOnlyOrNot includeHTTPOnly, IncludeSecureCookies includeSecureCookies, ShouldAskITP shouldAskITP = ShouldAskITP::Yes) 320 { 321 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); 322 323 BEGIN_BLOCK_OBJC_EXCEPTIONS; 324 325 NSArray *cookies = cookiesForURL(session, firstParty, sameSiteInfo, url, frameID, pageID, shouldAskITP); 320 return httpCookiesForURL(cookieStorage().get(), firstParty, sameSiteInfo, url); 321 } 322 323 std::pair<String, bool> NetworkStorageSession::cookiesForSession(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, IncludeHTTPOnlyOrNot includeHTTPOnly, IncludeSecureCookies includeSecureCookies, ShouldAskITP shouldAskITP) const 324 { 325 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 326 327 BEGIN_BLOCK_OBJC_EXCEPTIONS; 328 329 NSArray *cookies = cookiesForURL(firstParty, sameSiteInfo, url, frameID, pageID, shouldAskITP); 326 330 if (![cookies count]) 327 331 return { String(), false }; // Return a null string, not an empty one that StringBuilder would create below. … … 375 379 std::pair<String, bool> NetworkStorageSession::cookiesForDOM(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, IncludeSecureCookies includeSecureCookies, ShouldAskITP shouldAskITP) const 376 380 { 377 return cookiesForSession( *this,firstParty, sameSiteInfo, url, frameID, pageID, DoNotIncludeHTTPOnly, includeSecureCookies, shouldAskITP);381 return cookiesForSession(firstParty, sameSiteInfo, url, frameID, pageID, DoNotIncludeHTTPOnly, includeSecureCookies, shouldAskITP); 378 382 } 379 383 380 384 std::pair<String, bool> NetworkStorageSession::cookieRequestHeaderFieldValue(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, IncludeSecureCookies includeSecureCookies, ShouldAskITP shouldAskITP) const 381 385 { 382 return cookiesForSession( *this,firstParty, sameSiteInfo, url, frameID, pageID, IncludeHTTPOnly, includeSecureCookies, shouldAskITP);386 return cookiesForSession(firstParty, sameSiteInfo, url, frameID, pageID, IncludeHTTPOnly, includeSecureCookies, shouldAskITP); 383 387 } 384 388 385 389 std::pair<String, bool> NetworkStorageSession::cookieRequestHeaderFieldValue(const CookieRequestHeaderFieldProxy& headerFieldProxy) const 386 390 { 387 return cookiesForSession( *this,headerFieldProxy.firstParty, headerFieldProxy.sameSiteInfo, headerFieldProxy.url, headerFieldProxy.frameID, headerFieldProxy.pageID, IncludeHTTPOnly, headerFieldProxy.includeSecureCookies);391 return cookiesForSession(headerFieldProxy.firstParty, headerFieldProxy.sameSiteInfo, headerFieldProxy.url, headerFieldProxy.frameID, headerFieldProxy.pageID, IncludeHTTPOnly, headerFieldProxy.includeSecureCookies); 388 392 } 389 393 390 394 void NetworkStorageSession::setCookiesFromDOM(const URL& firstParty, const SameSiteInfo& sameSiteInfo, const URL& url, Optional<FrameIdentifier> frameID, Optional<PageIdentifier> pageID, ShouldAskITP shouldAskITP, const String& cookieStr) const 391 395 { 392 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );396 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 393 397 394 398 BEGIN_BLOCK_OBJC_EXCEPTIONS; … … 458 462 BEGIN_BLOCK_OBJC_EXCEPTIONS; 459 463 460 NSArray *cookies = cookiesForURL( *this,firstParty, sameSiteInfo, url, frameID, pageID, shouldAskITP);464 NSArray *cookies = cookiesForURL(firstParty, sameSiteInfo, url, frameID, pageID, shouldAskITP); 461 465 NSUInteger count = [cookies count]; 462 466 rawCookies.reserveCapacity(count); … … 519 523 void NetworkStorageSession::deleteCookiesForHostnames(const Vector<String>& hostnames, IncludeHttpOnlyCookies includeHttpOnlyCookies) 520 524 { 521 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) );525 ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies) || m_isInMemoryCookieStore); 522 526 523 527 BEGIN_BLOCK_OBJC_EXCEPTIONS; … … 567 571 } 568 572 573 Vector<Cookie> NetworkStorageSession::domCookiesForHost(const String& host) 574 { 575 NSArray *nsCookies = [nsCookieStorage() _getCookiesForDomain:(NSString *)host]; 576 return nsCookiesToCookieVector(nsCookies, [](NSHTTPCookie *cookie) { return !cookie.HTTPOnly; }); 577 } 578 579 #if HAVE(COOKIE_CHANGE_LISTENER_API) 580 581 void NetworkStorageSession::registerCookieChangeListenersIfNecessary() 582 { 583 if (m_didRegisterCookieListeners) 584 return; 585 586 m_didRegisterCookieListeners = true; 587 [nsCookieStorage() _setCookiesAddedHandler:^(NSArray<NSHTTPCookie *> * nsCookies, NSURL *urlForAddedCookies) { 588 Vector<Cookie> cookies = nsCookiesToCookieVector(nsCookies); 589 auto host = URL(urlForAddedCookies).host().toString(); 590 RELEASE_ASSERT(!host.isNull()); 591 auto it = m_cookieChangeObservers.find(host); 592 if (it == m_cookieChangeObservers.end()) 593 return; 594 for (auto* observer : it->value) 595 observer->cookiesAdded(host, cookies); 596 } onQueue:dispatch_get_main_queue()]; 597 [nsCookieStorage() _setCookiesDeletedHandler:^(NSArray<NSHTTPCookie *> *, bool /*deletedAllCookies*/) { 598 for (auto& observers : m_cookieChangeObservers.values()) { 599 for (auto* observer : observers) 600 observer->cookiesDeleted(); 601 } 602 } onQueue:dispatch_get_main_queue()]; 603 } 604 605 void NetworkStorageSession::unregisterCookieChangeListenersIfNecessary() 606 { 607 if (!m_didRegisterCookieListeners) 608 return; 609 610 [nsCookieStorage() _setCookiesAddedHandler:nil onQueue:nil]; 611 [nsCookieStorage() _setCookiesDeletedHandler:nil onQueue:nil]; 612 [nsCookieStorage() _setSubscribedDomainsForCookieChanges:nil]; 613 m_didRegisterCookieListeners = false; 614 } 615 616 void NetworkStorageSession::startListeningForCookieChangeNotifications(CookieChangeObserver& observer, const String& host) 617 { 618 registerCookieChangeListenersIfNecessary(); 619 620 auto& observers = m_cookieChangeObservers.ensure(host, [] { 621 return HashSet<CookieChangeObserver*> { }; 622 }).iterator->value; 623 ASSERT(!observers.contains(&observer)); 624 observers.add(&observer); 625 626 if (!m_subscribedDomainsForCookieChanges) 627 m_subscribedDomainsForCookieChanges = adoptNS([[NSMutableSet alloc] init]); 628 else if ([m_subscribedDomainsForCookieChanges containsObject:(NSString *)host]) 629 return; 630 631 [m_subscribedDomainsForCookieChanges addObject:(NSString *)host]; 632 [nsCookieStorage() _setSubscribedDomainsForCookieChanges:m_subscribedDomainsForCookieChanges.get()]; 633 } 634 635 void NetworkStorageSession::stopListeningForCookieChangeNotifications(CookieChangeObserver& observer, const HashSet<String>& hosts) 636 { 637 bool subscribedURLsChanged = false; 638 for (auto& host : hosts) { 639 auto it = m_cookieChangeObservers.find(host); 640 ASSERT(it != m_cookieChangeObservers.end()); 641 if (it == m_cookieChangeObservers.end()) 642 continue; 643 644 auto& observers = it->value; 645 ASSERT(observers.contains(&observer)); 646 observers.remove(&observer); 647 if (observers.isEmpty()) { 648 m_cookieChangeObservers.remove(it); 649 ASSERT([m_subscribedDomainsForCookieChanges containsObject:(NSString *)host]); 650 [m_subscribedDomainsForCookieChanges removeObject:(NSString *)host]; 651 subscribedURLsChanged = true; 652 } 653 } 654 if (subscribedURLsChanged) 655 [nsCookieStorage() _setSubscribedDomainsForCookieChanges:m_subscribedDomainsForCookieChanges.get()]; 656 } 657 658 // FIXME: This can eventually go away, this is merely to ensure a smooth transition to the new API. 659 bool NetworkStorageSession::supportsCookieChangeListenerAPI() const 660 { 661 static const bool supportsAPI = [nsCookieStorage() respondsToSelector:@selector(_setSubscribedDomainsForCookieChanges:)]; 662 return supportsAPI; 663 } 664 665 #endif // HAVE(COOKIE_CHANGE_LISTENER_API) 666 569 667 } // namespace WebCore -
trunk/Source/WebKit/ChangeLog
r256808 r256820 1 2020-02-17 Chris Dumez <cdumez@apple.com> 2 3 [WK2][Cocoa] Implement in-WebProcess cookie cache to avoid sync IPC for document.cookie in most cases 4 https://bugs.webkit.org/show_bug.cgi?id=207593 5 <rdar://problem/56027027> 6 7 Reviewed by Antti Koivisto. 8 9 See WebCore ChangeLog. 10 11 * NetworkProcess/NetworkConnectionToWebProcess.cpp: 12 (WebKit::NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess): 13 (WebKit::NetworkConnectionToWebProcess::domCookiesForHost): 14 (WebKit::NetworkConnectionToWebProcess::unsubscribeFromCookieChangeNotifications): 15 (WebKit::NetworkConnectionToWebProcess::cookiesAdded): 16 (WebKit::NetworkConnectionToWebProcess::cookiesDeleted): 17 * NetworkProcess/NetworkConnectionToWebProcess.h: 18 * NetworkProcess/NetworkConnectionToWebProcess.messages.in: 19 * Scripts/webkit/messages.py: 20 * Shared/WebPreferences.yaml: 21 * Sources.txt: 22 * SourcesCocoa.txt: 23 * WebKit.xcodeproj/project.pbxproj: 24 * WebProcess/Network/NetworkProcessConnection.cpp: 25 (WebKit::NetworkProcessConnection::cookiesAdded): 26 (WebKit::NetworkProcessConnection::cookiesDeleted): 27 * WebProcess/Network/NetworkProcessConnection.h: 28 * WebProcess/Network/NetworkProcessConnection.messages.in: 29 * WebProcess/WebPage/Cocoa/WebCookieCacheCocoa.mm: Copied from Source/WebKit/WebProcess/WebPage/WebCookieJar.h. 30 (WebKit::WebCookieCache::inMemoryStorageSession): 31 * WebProcess/WebPage/WebCookieCache.cpp: Added. 32 (WebKit::WebCookieCache::isFunctional): 33 (WebKit::WebCookieCache::cookiesForDOM): 34 (WebKit::WebCookieCache::setCookiesFromDOM): 35 (WebKit::WebCookieCache::cookiesAdded): 36 (WebKit::WebCookieCache::cookiesDeleted): 37 (WebKit::WebCookieCache::clear): 38 (WebKit::WebCookieCache::clearForHost): 39 (WebKit::WebCookieCache::pruneCacheIfNecessary): 40 * WebProcess/WebPage/WebCookieCache.h: Copied from Source/WebKit/WebProcess/WebPage/WebCookieJar.h. 41 * WebProcess/WebPage/WebCookieJar.cpp: 42 (WebKit::WebCookieJar::isEligibleForCache const): 43 (WebKit::WebCookieJar::cookies const): 44 (WebKit::WebCookieJar::setCookies): 45 (WebKit::WebCookieJar::cookiesAdded): 46 (WebKit::WebCookieJar::cookiesDeleted): 47 (WebKit::WebCookieJar::clearCache): 48 (WebKit::WebCookieJar::clearCacheForHost): 49 * WebProcess/WebPage/WebCookieJar.h: 50 * WebProcess/WebPage/WebPage.cpp: 51 (WebKit::m_overriddenMediaType): 52 * WebProcess/WebProcess.cpp: 53 (WebKit::WebProcess::WebProcess): 54 * WebProcess/WebProcess.h: 55 (WebKit::WebProcess::cookieJar): 56 1 57 2020-02-17 Chris Dumez <cdumez@apple.com> 2 58 -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
r256583 r256820 125 125 networkProcess().messagePortChannelRegistry().didCloseMessagePort(port); 126 126 127 #if HAVE(COOKIE_CHANGE_LISTENER_API) 128 if (auto* networkStorageSession = storageSession()) 129 networkStorageSession->stopListeningForCookieChangeNotifications(*this, m_hostsWithCookieListeners); 130 #endif 131 127 132 #if USE(LIBWEBRTC) 128 133 if (m_rtcProvider) … … 634 639 } 635 640 641 void NetworkConnectionToWebProcess::domCookiesForHost(const String& host, bool subscribeToCookieChangeNotifications, CompletionHandler<void(const Vector<WebCore::Cookie>&)>&& completionHandler) 642 { 643 auto* networkStorageSession = storageSession(); 644 if (!networkStorageSession) 645 return completionHandler({ }); 646 647 #if HAVE(COOKIE_CHANGE_LISTENER_API) 648 if (subscribeToCookieChangeNotifications) { 649 ASSERT(!m_hostsWithCookieListeners.contains(host)); 650 m_hostsWithCookieListeners.add(host); 651 networkStorageSession->startListeningForCookieChangeNotifications(*this, host); 652 } 653 #else 654 UNUSED_PARAM(subscribeToCookieChangeNotifications); 655 #endif 656 657 completionHandler(networkStorageSession->domCookiesForHost(host)); 658 } 659 660 #if HAVE(COOKIE_CHANGE_LISTENER_API) 661 662 void NetworkConnectionToWebProcess::unsubscribeFromCookieChangeNotifications(const HashSet<String>& hosts) 663 { 664 bool removed = m_hostsWithCookieListeners.remove(hosts.begin(), hosts.end()); 665 ASSERT_UNUSED(removed, removed); 666 667 if (auto* networkStorageSession = storageSession()) 668 networkStorageSession->stopListeningForCookieChangeNotifications(*this, hosts); 669 } 670 671 void NetworkConnectionToWebProcess::cookiesAdded(const String& host, const Vector<WebCore::Cookie>& cookies) 672 { 673 connection().send(Messages::NetworkProcessConnection::CookiesAdded(host, cookies), 0); 674 } 675 676 void NetworkConnectionToWebProcess::cookiesDeleted() 677 { 678 connection().send(Messages::NetworkProcessConnection::CookiesDeleted(), 0); 679 } 680 681 #endif 682 636 683 void NetworkConnectionToWebProcess::registerFileBlobURL(const URL& url, const String& path, SandboxExtension::Handle&& extensionHandle, const String& contentType) 637 684 { -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
r256583 r256820 43 43 #include <WebCore/MessagePortIdentifier.h> 44 44 #include <WebCore/NetworkLoadInformation.h> 45 #include <WebCore/NetworkStorageSession.h> 45 46 #include <WebCore/PageIdentifier.h> 46 47 #include <WebCore/ProcessIdentifier.h> … … 89 90 , public WebPaymentCoordinatorProxy::Client 90 91 #endif 92 #if HAVE(COOKIE_CHANGE_LISTENER_API) 93 , public WebCore::CookieChangeObserver 94 #endif 91 95 , IPC::Connection::Client { 92 96 public: … … 267 271 268 272 uint64_t nextMessageBatchIdentifier(Function<void()>&&); 273 274 void domCookiesForHost(const String& host, bool subscribeToCookieChangeNotifications, CompletionHandler<void(const Vector<WebCore::Cookie>&)>&&); 275 276 #if HAVE(COOKIE_CHANGE_LISTENER_API) 277 void unsubscribeFromCookieChangeNotifications(const HashSet<String>& hosts); 278 279 // WebCore::CookieChangeObserver. 280 void cookiesAdded(const String& host, const Vector<WebCore::Cookie>&) final; 281 void cookiesDeleted() final; 282 #endif 269 283 270 284 struct ResourceNetworkActivityTracker { … … 331 345 NetworkMDNSRegister m_mdnsRegister; 332 346 #endif 347 #if HAVE(COOKIE_CHANGE_LISTENER_API) 348 HashSet<String> m_hostsWithCookieListeners; 349 #endif 333 350 334 351 bool m_captureExtraNetworkLoadMetricsEnabled { false }; -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
r256583 r256820 40 40 GetRawCookies(URL firstParty, struct WebCore::SameSiteInfo sameSiteInfo, URL url, Optional<WebCore::FrameIdentifier> frameID, Optional<WebCore::PageIdentifier> pageID, enum:bool WebCore::ShouldAskITP shouldAskITP) -> (Vector<WebCore::Cookie> cookies) Synchronous 41 41 DeleteCookie(URL url, String cookieName) 42 DomCookiesForHost(String host, bool subscribeToCookieChangeNotifications) -> (Vector<WebCore::Cookie> cookies) Synchronous 43 #if HAVE(COOKIE_CHANGE_LISTENER_API) 44 UnsubscribeFromCookieChangeNotifications(HashSet<String> hosts) 45 #endif 42 46 43 47 RegisterFileBlobURL(URL url, String path, WebKit::SandboxExtension::Handle extensionHandle, String contentType) -
trunk/Source/WebKit/Scripts/webkit/messages.py
r256664 r256820 626 626 'WebCore::MediaEngineSupportParameters': ['<WebCore/MediaPlayer.h>'], 627 627 'WebCore::ISOWebVTTCue': ['<WebCore/ISOVTTCue.h>'], 628 'struct WebCore::Cookie': ['<WebCore/Cookie.h>'], 628 629 'struct WebCore::ElementContext': ['<WebCore/ElementContext.h>'], 629 630 'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'], -
trunk/Source/WebKit/Shared/WebPreferences.yaml
r256697 r256820 54 54 humanReadableName: "Automatic HTTPS upgrade" 55 55 humanReadableDescription: "Automatic HTTPS upgrade for known supported sites" 56 category: experimental 57 58 InProcessCookieCacheEnabled: 59 type: bool 60 defaultValue: true 61 humanReadableName: "In-Process Cookie Cache" 62 humanReadableDescription: "In-Process DOM Cookie Cache" 56 63 category: experimental 57 64 -
trunk/Source/WebKit/Sources.txt
r256353 r256820 625 625 WebProcess/WebPage/WebBackForwardListProxy.cpp 626 626 WebProcess/WebPage/WebContextMenu.cpp 627 WebProcess/WebPage/WebCookieCache.cpp 627 628 WebProcess/WebPage/WebCookieJar.cpp 628 629 WebProcess/WebPage/WebDocumentLoader.cpp -
trunk/Source/WebKit/SourcesCocoa.txt
r255998 r256820 614 614 615 615 WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm 616 WebProcess/WebPage/Cocoa/WebCookieCacheCocoa.mm 616 617 WebProcess/WebPage/Cocoa/WebPageCocoa.mm 617 618 WebProcess/WebPage/Cocoa/WebRemoteObjectRegistry.cpp -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r256756 r256820 944 944 4671FF1F23217EFF001B64C7 /* WebResourceLoadObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4671FF1D23217EFF001B64C7 /* WebResourceLoadObserver.h */; }; 945 945 467E43E82243FF7D00B13924 /* WebProcessDataStoreParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 467E43E72243FF6D00B13924 /* WebProcessDataStoreParameters.h */; }; 946 46809A7C23D9225E00C297D0 /* WebCookieCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 46809A7A23D9225300C297D0 /* WebCookieCache.h */; }; 946 947 46A2B6091E5676A600C3DEDA /* BackgroundProcessResponsivenessTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */; }; 947 948 46B0524722668D8500265B97 /* WebDeviceOrientationAndMotionAccessController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B0524422668D2300265B97 /* WebDeviceOrientationAndMotionAccessController.h */; }; … … 3487 3488 4671FF1E23217EFF001B64C7 /* WebResourceLoadObserver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebResourceLoadObserver.cpp; sourceTree = "<group>"; }; 3488 3489 467E43E72243FF6D00B13924 /* WebProcessDataStoreParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebProcessDataStoreParameters.h; sourceTree = "<group>"; }; 3490 46809A7A23D9225300C297D0 /* WebCookieCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCookieCache.h; sourceTree = "<group>"; }; 3491 46809A7B23D9225300C297D0 /* WebCookieCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCookieCache.cpp; sourceTree = "<group>"; }; 3489 3492 4683569A21E81CC7006E27A3 /* ProvisionalPageProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProvisionalPageProxy.h; sourceTree = "<group>"; }; 3490 3493 4683569B21E81CC7006E27A3 /* ProvisionalPageProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProvisionalPageProxy.cpp; sourceTree = "<group>"; }; … … 8429 8432 51871B59127CB89D00F76232 /* WebContextMenu.cpp */, 8430 8433 51871B5A127CB89D00F76232 /* WebContextMenu.h */, 8434 46809A7B23D9225300C297D0 /* WebCookieCache.cpp */, 8435 46809A7A23D9225300C297D0 /* WebCookieCache.h */, 8431 8436 5C7FB46E21E97C0B009E3241 /* WebCookieJar.cpp */, 8432 8437 5C7FB46F21E97C0C009E3241 /* WebCookieJar.h */, … … 10669 10674 51ACBBA0127A8F2C00D203B9 /* WebContextMenuProxyMac.h in Headers */, 10670 10675 BCF4DE25168FA44800C94AFC /* WebContextSupplement.h in Headers */, 10676 46809A7C23D9225E00C297D0 /* WebCookieCache.h in Headers */, 10671 10677 5C7FB47021E97DC5009E3241 /* WebCookieJar.h in Headers */, 10672 10678 330934501315B94D0097A7BC /* WebCookieManager.h in Headers */, -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
r256303 r256820 33 33 #include "StorageAreaMapMessages.h" 34 34 #include "WebCacheStorageProvider.h" 35 #include "WebCookieJar.h" 35 36 #include "WebCoreArgumentCoders.h" 36 37 #include "WebIDBConnectionToServer.h" … … 235 236 } 236 237 238 #if HAVE(COOKIE_CHANGE_LISTENER_API) 239 void NetworkProcessConnection::cookiesAdded(const String& host, const Vector<WebCore::Cookie>& cookies) 240 { 241 WebProcess::singleton().cookieJar().cookiesAdded(host, cookies); 242 } 243 244 void NetworkProcessConnection::cookiesDeleted() 245 { 246 WebProcess::singleton().cookieJar().cookiesDeleted(); 247 } 248 #endif 249 237 250 #if ENABLE(SHAREABLE_RESOURCE) 238 251 void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle) -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.h
r254931 r256820 42 42 class ResourceRequest; 43 43 class ResourceResponse; 44 struct Cookie; 44 45 struct MessagePortIdentifier; 45 46 struct MessageWithMessagePorts; … … 84 85 bool cookiesEnabled() const; 85 86 87 #if HAVE(COOKIE_CHANGE_LISTENER_API) 88 void cookiesAdded(const String& host, const Vector<WebCore::Cookie>&); 89 void cookiesDeleted(); 90 #endif 91 86 92 private: 87 93 NetworkProcessConnection(IPC::Connection::Identifier, WebCore::HTTPCookieAcceptPolicy); -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.messages.in
r254931 r256820 32 32 CookieAcceptPolicyChanged(enum:uint8_t WebCore::HTTPCookieAcceptPolicy policy); 33 33 34 #if HAVE(COOKIE_CHANGE_LISTENER_API) 35 CookiesAdded(String host, Vector<struct WebCore::Cookie> cookies); 36 CookiesDeleted(); 37 #endif 38 34 39 CheckProcessLocalPortForActivity(struct WebCore::MessagePortIdentifier port) -> (WebCore::MessagePortChannelProvider::HasActivity hasActivity) Async 35 40 MessagesAvailableForPort(struct WebCore::MessagePortIdentifier port) -
trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebCookieCacheCocoa.mm
r256808 r256820 1 1 /* 2 * Copyright (C) 20 19Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #pragma once 26 #import "config.h" 27 #import "WebCookieCache.h" 27 28 28 #include <WebCore/CookieJar.h> 29 #import "WebProcess.h" 30 #import <WebCore/NetworkStorageSession.h> 29 31 30 32 namespace WebKit { 31 33 32 class WebCookieJar final : public WebCore::CookieJar { 33 public: 34 static Ref<WebCookieJar> create() { return adoptRef(*new WebCookieJar); } 35 36 String cookies(WebCore::Document&, const URL&) const final; 37 void setCookies(WebCore::Document&, const URL&, const String& cookieString) final; 38 bool cookiesEnabled(const WebCore::Document&) const final; 39 std::pair<String, WebCore::SecureCookiesAccessed> cookieRequestHeaderFieldValue(const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<WebCore::FrameIdentifier>, Optional<WebCore::PageIdentifier>, WebCore::IncludeSecureCookies) const final; 40 bool getRawCookies(const WebCore::Document&, const URL&, Vector<WebCore::Cookie>&) const final; 41 void deleteCookie(const WebCore::Document&, const URL&, const String& cookieName) final; 42 private: 43 WebCookieJar(); 44 }; 34 using namespace WebCore; 35 36 NetworkStorageSession& WebCookieCache::inMemoryStorageSession() 37 { 38 if (!m_inMemoryStorageSession) { 39 String sessionName = makeString("WebKitInProcessStorage-", getCurrentProcessID()); 40 auto storageSession = adoptCF(WebCore::createPrivateStorageSession(sessionName.createCFString().get())); 41 auto cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, storageSession.get())); 42 m_inMemoryStorageSession = makeUnique<NetworkStorageSession>(WebProcess::singleton().sessionID(), WTFMove(storageSession), WTFMove(cookieStorage), NetworkStorageSession::IsInMemoryCookieStore::Yes); 43 } 44 return *m_inMemoryStorageSession; 45 } 45 46 46 47 } // namespace WebKit -
trunk/Source/WebKit/WebProcess/WebPage/WebCookieCache.h
r256808 r256820 1 1 /* 2 * Copyright (C) 20 19Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 28 28 #include <WebCore/CookieJar.h> 29 #include <WebCore/SameSiteInfo.h> 30 #include <wtf/HashSet.h> 31 32 namespace WebCore { 33 class NetworkStorageSession; 34 } 29 35 30 36 namespace WebKit { 31 37 32 class WebCookie Jar final : public WebCore::CookieJar{38 class WebCookieCache { 33 39 public: 34 static Ref<WebCookieJar> create() { return adoptRef(*new WebCookieJar); } 35 36 String cookies(WebCore::Document&, const URL&) const final; 37 void setCookies(WebCore::Document&, const URL&, const String& cookieString) final; 38 bool cookiesEnabled(const WebCore::Document&) const final; 39 std::pair<String, WebCore::SecureCookiesAccessed> cookieRequestHeaderFieldValue(const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, Optional<WebCore::FrameIdentifier>, Optional<WebCore::PageIdentifier>, WebCore::IncludeSecureCookies) const final; 40 bool getRawCookies(const WebCore::Document&, const URL&, Vector<WebCore::Cookie>&) const final; 41 void deleteCookie(const WebCore::Document&, const URL&, const String& cookieName) final; 40 WebCookieCache() = default; 41 42 bool isSupported(); 43 44 String cookiesForDOM(const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, WebCore::FrameIdentifier, WebCore::PageIdentifier, WebCore::IncludeSecureCookies); 45 void setCookiesFromDOM(const URL& firstParty, const WebCore::SameSiteInfo&, const URL&, WebCore::FrameIdentifier, WebCore::PageIdentifier, const String& cookieString); 46 47 void cookiesAdded(const String& host, const Vector<WebCore::Cookie>&); 48 void cookiesDeleted(); 49 50 void clear(); 51 void clearForHost(const String&); 52 42 53 private: 43 WebCookieJar(); 54 WebCore::NetworkStorageSession& inMemoryStorageSession(); 55 void pruneCacheIfNecessary(); 56 57 HashSet<String> m_hostsWithInMemoryStorage; 58 std::unique_ptr<WebCore::NetworkStorageSession> m_inMemoryStorageSession; 44 59 }; 45 60 -
trunk/Source/WebKit/WebProcess/WebPage/WebCookieJar.cpp
r254931 r256820 1 1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 #include <WebCore/FrameLoader.h> 39 39 #include <WebCore/FrameLoaderClient.h> 40 #include <WebCore/Settings.h> 40 41 #include <WebCore/StorageSessionProvider.h> 41 42 … … 89 90 #endif 90 91 92 bool WebCookieJar::isEligibleForCache(WebFrame& frame, const URL& firstPartyForCookies, const URL& resourceURL) const 93 { 94 auto* page = frame.page() ? frame.page()->corePage() : nullptr; 95 if (!page || !page->settings().inProcessCookieCacheEnabled()) 96 return false; 97 98 if (!m_cache.isSupported()) 99 return false; 100 101 // For now, we only cache cookies for first-party content. Third-party cookie caching is a bit more complicated due to partitioning and storage access. 102 RegistrableDomain resourceDomain { resourceURL }; 103 if (resourceDomain.isEmpty()) 104 return false; 105 106 return frame.isMainFrame() || RegistrableDomain { firstPartyForCookies } == resourceDomain; 107 } 108 91 109 String WebCookieJar::cookies(WebCore::Document& document, const URL& url) const 92 110 { … … 101 119 #endif 102 120 121 auto sameSiteInfo = CookieJar::sameSiteInfo(document); 122 auto includeSecureCookies = CookieJar::shouldIncludeSecureCookies(document, url); 103 123 auto frameID = webFrame->frameID(); 104 124 auto pageID = webFrame->page()->identifier(); 105 125 126 if (isEligibleForCache(*webFrame, document.firstPartyForCookies(), url)) 127 return m_cache.cookiesForDOM(document.firstPartyForCookies(), sameSiteInfo, url, frameID, pageID, includeSecureCookies); 128 106 129 String cookieString; 107 130 bool secureCookiesAccessed = false; 108 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::CookiesForDOM(document.firstPartyForCookies(), sameSiteInfo (document), url, frameID, pageID, shouldIncludeSecureCookies(document, url), shouldAskITPInNetworkProcess), Messages::NetworkConnectionToWebProcess::CookiesForDOM::Reply(cookieString, secureCookiesAccessed), 0))131 if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::CookiesForDOM(document.firstPartyForCookies(), sameSiteInfo, url, frameID, pageID, includeSecureCookies, shouldAskITPInNetworkProcess), Messages::NetworkConnectionToWebProcess::CookiesForDOM::Reply(cookieString, secureCookiesAccessed), 0)) 109 132 return { }; 110 133 … … 124 147 #endif 125 148 149 auto sameSiteInfo = CookieJar::sameSiteInfo(document); 126 150 auto frameID = webFrame->frameID(); 127 151 auto pageID = webFrame->page()->identifier(); 128 152 129 WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCookiesFromDOM(document.firstPartyForCookies(), sameSiteInfo(document), url, frameID, pageID, shouldAskITPInNetworkProcess, cookieString), 0); 153 if (isEligibleForCache(*webFrame, document.firstPartyForCookies(), url)) 154 m_cache.setCookiesFromDOM(document.firstPartyForCookies(), sameSiteInfo, url, frameID, pageID, cookieString); 155 156 WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCookiesFromDOM(document.firstPartyForCookies(), sameSiteInfo, url, frameID, pageID, shouldAskITPInNetworkProcess, cookieString), 0); 157 } 158 159 void WebCookieJar::cookiesAdded(const String& host, const Vector<WebCore::Cookie>& cookies) 160 { 161 m_cache.cookiesAdded(host, cookies); 162 } 163 164 void WebCookieJar::cookiesDeleted() 165 { 166 m_cache.cookiesDeleted(); 167 } 168 169 void WebCookieJar::clearCache() 170 { 171 m_cache.clear(); 172 } 173 174 void WebCookieJar::clearCacheForHost(const String& host) 175 { 176 m_cache.clearForHost(host); 130 177 } 131 178 -
trunk/Source/WebKit/WebProcess/WebPage/WebCookieJar.h
r250153 r256820 1 1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include "WebCookieCache.h" 28 29 #include <WebCore/CookieJar.h> 29 30 31 namespace WebCore { 32 struct Cookie; 33 } 34 30 35 namespace WebKit { 36 37 class WebFrame; 31 38 32 39 class WebCookieJar final : public WebCore::CookieJar { … … 40 47 bool getRawCookies(const WebCore::Document&, const URL&, Vector<WebCore::Cookie>&) const final; 41 48 void deleteCookie(const WebCore::Document&, const URL&, const String& cookieName) final; 49 50 void cookiesAdded(const String& host, const Vector<WebCore::Cookie>&); 51 void cookiesDeleted(); 52 42 53 private: 43 54 WebCookieJar(); 55 56 void clearCache() final; 57 void clearCacheForHost(const String&) final; 58 bool isEligibleForCache(WebFrame&, const URL& firstPartyForCookies, const URL& resourceURL) const; 59 60 mutable WebCookieCache m_cache; 44 61 }; 45 62 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r256715 r256820 467 467 WebProcess::singleton().cacheStorageProvider(), 468 468 WebBackForwardListProxy::create(*this), 469 Web CookieJar::create(),469 WebProcess::singleton().cookieJar(), 470 470 makeUniqueRef<WebProgressTrackerClient>(*this), 471 471 makeUniqueRef<MediaRecorderProvider>() -
trunk/Source/WebKit/WebProcess/WebProcess.cpp
r256742 r256820 49 49 #include "WebCacheStorageProvider.h" 50 50 #include "WebConnectionToUIProcess.h" 51 #include "WebCookieJar.h" 51 52 #include "WebCoreArgumentCoders.h" 52 53 #include "WebFrame.h" … … 206 207 , m_webLoaderStrategy(*new WebLoaderStrategy) 207 208 , m_cacheStorageProvider(WebCacheStorageProvider::create()) 209 , m_cookieJar(WebCookieJar::create()) 208 210 , m_dnsPrefetchHystereris([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) m_dnsPrefetchedHosts.clear(); }) 209 211 #if ENABLE(NETSCAPE_PLUGIN_API) -
trunk/Source/WebKit/WebProcess/WebProcess.h
r256756 r256820 121 121 class WebAutomationSessionProxy; 122 122 class WebCacheStorageProvider; 123 class WebCookieJar; 123 124 class WebCompiledContentRuleListData; 124 125 class WebConnectionToUIProcess; … … 294 295 295 296 WebCacheStorageProvider& cacheStorageProvider() { return m_cacheStorageProvider.get(); } 297 WebCookieJar& cookieJar() { return m_cookieJar.get(); } 296 298 WebSocketChannelManager& webSocketChannelManager() { return m_webSocketChannelManager; } 297 299 … … 559 561 560 562 Ref<WebCacheStorageProvider> m_cacheStorageProvider; 563 Ref<WebCookieJar> m_cookieJar; 561 564 WebSocketChannelManager m_webSocketChannelManager; 562 565 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CookieAcceptPolicy.mm
r242339 r256820 33 33 #import <pal/spi/cf/CFNetworkSPI.h> 34 34 #import <wtf/RetainPtr.h> 35 36 // FIXME: This test is causing flakiness in API tests. It sets the cookie accept policy to 'Never' 37 // and following tests often are unable to set cookies. 38 #if !PLATFORM(IOS_FAMILY) 35 39 36 40 static bool receivedScriptMessage = false; … … 73 77 [[NSHTTPCookieStorage sharedHTTPCookieStorage] _saveCookies]; 74 78 } 79 80 #endif // !PLATFORM(IOS_FAMILY) -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/CookiePrivateBrowsing.mm
r242339 r256820 27 27 28 28 #import "PlatformUtilities.h" 29 #import "Test.h" 30 #import "TestWKWebView.h" 29 31 #import <WebKit/WKProcessPool.h> 30 32 #import <WebKit/WKProcessPoolPrivate.h> … … 32 34 #import <WebKit/WKWebViewConfiguration.h> 33 35 #import <wtf/RetainPtr.h> 36 #import <wtf/text/WTFString.h> 34 37 35 38 static bool receivedAlert; … … 69 72 TestWebKitAPI::Util::run(&receivedAlert); 70 73 } 74 75 TEST(WebKit, CookieCacheSyncAcrossProcess) 76 { 77 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 78 [configuration setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]]; 79 auto view1 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 80 auto view2 = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 81 [view1 synchronouslyLoadHTMLString:@"foo" baseURL:[NSURL URLWithString:@"http://example.com/"]]; 82 [view2 synchronouslyLoadHTMLString:@"bar" baseURL:[NSURL URLWithString:@"http://example.com/"]]; 83 84 // Cache DOM cookies in first WebView. 85 __block bool doneEvaluatingJavaScript = false; 86 [view1 evaluateJavaScript:@"document.cookie;" completionHandler:^(id _Nullable cookie, NSError * _Nullable error) { 87 EXPECT_NULL(error); 88 EXPECT_TRUE([cookie isKindOfClass:[NSString class]]); 89 EXPECT_WK_STREQ("", (NSString *)cookie); 90 doneEvaluatingJavaScript = true; 91 }]; 92 TestWebKitAPI::Util::run(&doneEvaluatingJavaScript); 93 94 // Cache DOM cookies in second WebView. 95 doneEvaluatingJavaScript = false; 96 [view2 evaluateJavaScript:@"document.cookie;" completionHandler:^(id _Nullable cookie, NSError * _Nullable error) { 97 EXPECT_NULL(error); 98 EXPECT_TRUE([cookie isKindOfClass:[NSString class]]); 99 EXPECT_WK_STREQ("", (NSString *)cookie); 100 doneEvaluatingJavaScript = true; 101 }]; 102 TestWebKitAPI::Util::run(&doneEvaluatingJavaScript); 103 104 // Setting cookie in first Webview / process. 105 doneEvaluatingJavaScript = false; 106 [view1 evaluateJavaScript:@"document.cookie = 'foo=bar'; document.cookie;" completionHandler:^(id _Nullable cookie, NSError * _Nullable error) { 107 EXPECT_NULL(error); 108 EXPECT_TRUE([cookie isKindOfClass:[NSString class]]); 109 EXPECT_WK_STREQ("foo=bar", (NSString *)cookie); 110 doneEvaluatingJavaScript = true; 111 }]; 112 TestWebKitAPI::Util::run(&doneEvaluatingJavaScript); 113 114 // Making sure new cookie gets sync'd to second WebView process. 115 int timeout = 0; 116 __block String cookieString; 117 do { 118 TestWebKitAPI::Util::sleep(0.1); 119 doneEvaluatingJavaScript = false; 120 [view2 evaluateJavaScript:@"document.cookie;" completionHandler:^(id _Nullable cookie, NSError * _Nullable error) { 121 EXPECT_NULL(error); 122 EXPECT_TRUE([cookie isKindOfClass:[NSString class]]); 123 cookieString = (NSString *)cookie; 124 doneEvaluatingJavaScript = true; 125 }]; 126 TestWebKitAPI::Util::run(&doneEvaluatingJavaScript); 127 ++timeout; 128 } while (cookieString != "" && timeout < 50); 129 EXPECT_WK_STREQ("foo=bar", cookieString); 130 }
Note:
See TracChangeset
for help on using the changeset viewer.