Title: [219683] trunk/Source/WebCore
Revision
219683
Author
beid...@apple.com
Date
2017-07-20 07:28:18 -0700 (Thu, 20 Jul 2017)

Log Message

WKHTTPCookieStore API tests fail on High Sierra.
<rdar://problem/33410271> and https://bugs.webkit.org/show_bug.cgi?id=174666

Reviewed by Andy Estes.

Covered by existing API tests.

In r219567 I'd moved cookie storage observation off of NSHTTPCookieStorage and NSNotificationCenter
to CFHTTPCookieStorage observation callbacks.

This is because notifications were only sent for the default [NSHTTPCookieStorage sharedHTTPCookieStorage]
and not any of the other ones we keep in flight.

Unfortunately that SPI has been disabled in High Sierra.
Fortunately we found a way we can get non-shared NSHTTPCookieStorages to send notifications that works everywhere.

* platform/network/cocoa/CookieStorageObserver.h:
* platform/network/cocoa/CookieStorageObserver.mm:
(-[WebCookieObserverAdapter initWithObserver:]):
(-[WebCookieObserverAdapter cookiesChangedNotificationHandler:]):
(WebCore::CookieStorageObserver::create):
(WebCore::CookieStorageObserver::CookieStorageObserver):
(WebCore::CookieStorageObserver::~CookieStorageObserver):
(WebCore::CookieStorageObserver::startObserving): Use a trick to call some SPI on non-shared NSHTTPCookieStorages
  to get them to send notifications.
(WebCore::CookieStorageObserver::stopObserving):
(WebCore::cookiesChanged): Deleted.

* platform/network/cocoa/NetworkStorageSessionCocoa.mm:
(WebCore::NetworkStorageSession::cookieStorageObserver):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (219682 => 219683)


--- trunk/Source/WebCore/ChangeLog	2017-07-20 14:25:34 UTC (rev 219682)
+++ trunk/Source/WebCore/ChangeLog	2017-07-20 14:28:18 UTC (rev 219683)
@@ -1,3 +1,36 @@
+2017-07-20  Brady Eidson  <beid...@apple.com>
+
+        WKHTTPCookieStore API tests fail on High Sierra.
+        <rdar://problem/33410271> and https://bugs.webkit.org/show_bug.cgi?id=174666
+
+        Reviewed by Andy Estes.
+
+        Covered by existing API tests.
+
+        In r219567 I'd moved cookie storage observation off of NSHTTPCookieStorage and NSNotificationCenter
+        to CFHTTPCookieStorage observation callbacks.
+        
+        This is because notifications were only sent for the default [NSHTTPCookieStorage sharedHTTPCookieStorage]
+        and not any of the other ones we keep in flight.
+        
+        Unfortunately that SPI has been disabled in High Sierra.
+        Fortunately we found a way we can get non-shared NSHTTPCookieStorages to send notifications that works everywhere.
+        
+        * platform/network/cocoa/CookieStorageObserver.h:
+        * platform/network/cocoa/CookieStorageObserver.mm:
+        (-[WebCookieObserverAdapter initWithObserver:]):
+        (-[WebCookieObserverAdapter cookiesChangedNotificationHandler:]):
+        (WebCore::CookieStorageObserver::create):
+        (WebCore::CookieStorageObserver::CookieStorageObserver):
+        (WebCore::CookieStorageObserver::~CookieStorageObserver):
+        (WebCore::CookieStorageObserver::startObserving): Use a trick to call some SPI on non-shared NSHTTPCookieStorages
+          to get them to send notifications.
+        (WebCore::CookieStorageObserver::stopObserving):
+        (WebCore::cookiesChanged): Deleted.
+
+        * platform/network/cocoa/NetworkStorageSessionCocoa.mm:
+        (WebCore::NetworkStorageSession::cookieStorageObserver):
+
 2017-07-20  Miguel Gomez  <mago...@igalia.com>
 
         [GStreamer] Some layout tests issue "g_mutex_clear() called on uninitialised or locked mutex" and flaky crash in ~MediaPlayerPrivateGStreamerBase

Modified: trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.h (219682 => 219683)


--- trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.h	2017-07-20 14:25:34 UTC (rev 219682)
+++ trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.h	2017-07-20 14:28:18 UTC (rev 219683)
@@ -30,12 +30,15 @@
 #include <wtf/RetainPtr.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
+OBJC_CLASS NSHTTPCookieStorage;
+OBJC_CLASS WebCookieObserverAdapter;
+
 namespace WebCore {
 
 class CookieStorageObserver : public ThreadSafeRefCounted<CookieStorageObserver> {
 public:
-    static RefPtr<CookieStorageObserver> create(CFHTTPCookieStorageRef);
-    CookieStorageObserver(CFHTTPCookieStorageRef);
+    static RefPtr<CookieStorageObserver> create(NSHTTPCookieStorage *);
+    CookieStorageObserver(NSHTTPCookieStorage *);
     ~CookieStorageObserver();
 
     void startObserving(WTF::Function<void()>&& callback);
@@ -44,7 +47,9 @@
     void cookiesDidChange();
 
 private:
-    RetainPtr<CFHTTPCookieStorageRef> m_cookieStorage;
+    RetainPtr<NSHTTPCookieStorage> m_cookieStorage;
+    bool m_hasRegisteredInternalsForNotifications { false };
+    RetainPtr<WebCookieObserverAdapter> m_observerAdapter;
     WTF::Function<void()> m_cookieChangeCallback;
 };
 

Modified: trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.mm (219682 => 219683)


--- trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.mm	2017-07-20 14:25:34 UTC (rev 219682)
+++ trunk/Source/WebCore/platform/network/cocoa/CookieStorageObserver.mm	2017-07-20 14:28:18 UTC (rev 219683)
@@ -29,20 +29,52 @@
 #import "NSURLConnectionSPI.h"
 #import <wtf/MainThread.h>
 
-namespace WebCore {
+@interface WebNSHTTPCookieStorageInternal : NSObject {
+@public
+    id internal;
+}
+@end
 
-static void cookiesChanged(CFHTTPCookieStorageRef, void* context)
+@implementation WebNSHTTPCookieStorageInternal
+@end
+
+@interface WebCookieObserverAdapter : NSObject {
+    WebCore::CookieStorageObserver* observer;
+}
+- (instancetype)initWithObserver:(WebCore::CookieStorageObserver&)theObserver;
+- (void)cookiesChangedNotificationHandler:(NSNotification *)notification;
+
+@end
+
+@implementation WebCookieObserverAdapter
+
+- (instancetype)initWithObserver:(WebCore::CookieStorageObserver&)theObserver
 {
-    ASSERT(!isMainThread());
-    static_cast<CookieStorageObserver*>(context)->cookiesDidChange();
+    self = [super init];
+    if (!self)
+        return nil;
+
+    observer = &theObserver;
+
+    return self;
 }
 
-RefPtr<CookieStorageObserver> CookieStorageObserver::create(CFHTTPCookieStorageRef cookieStorage)
+- (void)cookiesChangedNotificationHandler:(NSNotification *)notification
 {
+    UNUSED_PARAM(notification);
+    observer->cookiesDidChange();
+}
+
+@end
+
+namespace WebCore {
+
+RefPtr<CookieStorageObserver> CookieStorageObserver::create(NSHTTPCookieStorage *cookieStorage)
+{
     return adoptRef(new CookieStorageObserver(cookieStorage));
 }
 
-CookieStorageObserver::CookieStorageObserver(CFHTTPCookieStorageRef cookieStorage)
+CookieStorageObserver::CookieStorageObserver(NSHTTPCookieStorage *cookieStorage)
     : m_cookieStorage(cookieStorage)
 {
     ASSERT(isMainThread());
@@ -53,8 +85,10 @@
 {
     ASSERT(isMainThread());
 
-    if (m_cookieChangeCallback)
+    if (m_cookieChangeCallback) {
+        ASSERT(m_observerAdapter);
         stopObserving();
+    }
 }
 
 void CookieStorageObserver::startObserving(WTF::Function<void()>&& callback)
@@ -61,10 +95,23 @@
 {
     ASSERT(isMainThread());
     ASSERT(!m_cookieChangeCallback);
+    ASSERT(!m_observerAdapter);
+
     m_cookieChangeCallback = WTFMove(callback);
+    m_observerAdapter = adoptNS([[WebCookieObserverAdapter alloc] initWithObserver:*this]);
 
-    CFHTTPCookieStorageAddObserver(m_cookieStorage.get(), [NSURLConnection resourceLoaderRunLoop], kCFRunLoopCommonModes, cookiesChanged, this);
-    CFHTTPCookieStorageScheduleWithRunLoop(m_cookieStorage.get(), [NSURLConnection resourceLoaderRunLoop], kCFRunLoopCommonModes);
+    if (!m_hasRegisteredInternalsForNotifications) {
+        if (m_cookieStorage.get() != [NSHTTPCookieStorage sharedHTTPCookieStorage]) {
+            auto selector = NSSelectorFromString(@"registerForPostingNotificationsWithContext:");
+            id internalObject = (static_cast<WebNSHTTPCookieStorageInternal *>(m_cookieStorage.get()))->internal;
+            RELEASE_ASSERT([internalObject respondsToSelector:selector]);
+            [internalObject performSelector:selector withObject:m_cookieStorage.get()];
+        }
+
+        m_hasRegisteredInternalsForNotifications = true;
+    }
+
+    [[NSNotificationCenter defaultCenter] addObserver:m_observerAdapter.get() selector:@selector(cookiesChangedNotificationHandler:) name:NSHTTPCookieManagerCookiesChangedNotification object:m_cookieStorage.get()];
 }
 
 void CookieStorageObserver::stopObserving()
@@ -71,9 +118,12 @@
 {
     ASSERT(isMainThread());
     ASSERT(m_cookieChangeCallback);
+    ASSERT(m_observerAdapter);
+
+    [[NSNotificationCenter defaultCenter] removeObserver:m_observerAdapter.get() name:NSHTTPCookieManagerCookiesChangedNotification object:nil];
+
     m_cookieChangeCallback = nullptr;
-
-    CFHTTPCookieStorageRemoveObserver(m_cookieStorage.get(), [NSURLConnection resourceLoaderRunLoop], kCFRunLoopCommonModes, cookiesChanged, this);
+    m_observerAdapter = nil;
 }
 
 void CookieStorageObserver::cookiesDidChange()

Modified: trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm (219682 => 219683)


--- trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm	2017-07-20 14:25:34 UTC (rev 219682)
+++ trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm	2017-07-20 14:28:18 UTC (rev 219683)
@@ -94,7 +94,7 @@
 CookieStorageObserver& NetworkStorageSession::cookieStorageObserver() const
 {
     if (!m_cookieStorageObserver)
-        m_cookieStorageObserver = CookieStorageObserver::create([nsCookieStorage() _cookieStorage]);
+        m_cookieStorageObserver = CookieStorageObserver::create(nsCookieStorage());
 
     return *m_cookieStorageObserver;
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to