Bug 185483 - iOS 11.3 delays creation of WKWebsiteDataStore and queues setCookie completion handler
Summary: iOS 11.3 delays creation of WKWebsiteDataStore and queues setCookie completio...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit API (show other bugs)
Version: Other
Hardware: iPhone / iPad iOS 11
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-05-09 12:02 PDT by Harry Shamansky
Modified: 2018-07-25 12:27 PDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Harry Shamansky 2018-05-09 12:02:34 PDT
We have the following flow in our app: If navigating to a particular URL in a WKWebView that requires a cookie, cancel the navigation, set a cookie, and in the cookie setter's completion block, load the original URL in the web view.

However, new behavior added by https://github.com/WebKit/webkit/commit/d9d6e5c82c4a74cd573f3f119f166ffcee477b04 delays the creation of the WKWebsiteDataStore such that the completion block is queued until "necessary", and WebKit never actually considers its creation "necessary" since we only load the URL in the completion block. It's essentially a deadlock.

Here's sample code:
```
if (@available(iOS 11.0, *)) {
        [webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie
                                                        completionHandler:^{
            [webView loadRequest:request];
        }];
}
```

This was caused by rdar://problem/33164453 (see also https://bugs.webkit.org/show_bug.cgi?id=176551)

Steps to Reproduce:
Cancel web view navigation, set a cookie with a completion handler that loads the original (canceled) URL. Take no other action on the web view.

Expected Results:
The cookie is set and the completion handler is called.

Actual Results:
The cookie is not set (and the completion handler is not called) until another action is taken on the WKWebView that requires the WKWebsiteDataStore to be initialized.

Version/Build:
Issue affects iOS 11.3+ only. Rarely reproduces on simulator; frequently but not always reproduces on device.

Configuration:
iPhone X 11.3

Filed as rdar://40100673
Comment 1 Chris Dumez 2018-07-25 12:27:50 PDT
Would you be able to provide a minimal test app? Looking at our code, we always call the completion handler right away:
void HTTPCookieStore::setCookie(const WebCore::Cookie& cookie, Function<void ()>&& completionHandler)
{
    auto* pool = m_owningDataStore->processPoolForCookieStorageOperations();
    if (!pool) {
        // FIXME: pendingCookies used for defaultSession because session cookies cannot be propagated to Network Process with uiProcessCookieStorageIdentifier.
        if (m_owningDataStore->sessionID() == PAL::SessionID::defaultSessionID() && !cookie.session)
            WebCore::NetworkStorageSession::defaultStorageSession().setCookie(cookie);
        else
            m_owningDataStore->addPendingCookie(cookie);

        // Calls the completion handler right away if we do not have a pool yet.
        callOnMainThread([completionHandler = WTFMove(completionHandler)]() {
            completionHandler();
        });
        return;
    }

    // This sends an IPC to the network process (starting it if it is not running) and we call the completion handler when the network process has processed the IPC.
    auto* cookieManager = pool->supplement<WebKit::WebCookieManagerProxy>();
    cookieManager->setCookie(m_owningDataStore->sessionID(), cookie, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
        completionHandler();
    });
}

The code you mention that appends cookies does not delay the call of the completion handler.

Also note that we've made fixes in iOS 12 beta, did you test it?