Add SPI to preconnect to a server
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Jun 2020 20:59:20 +0000 (20:59 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Jun 2020 20:59:20 +0000 (20:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=213109
<rdar://problem/64184412>

Patch by Alex Christensen <achristensen@webkit.org> on 2020-06-15
Reviewed by Geoff Garen.

Source/WebKit:

Covered by API tests.

* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _preconnectToServer:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::preconnectTo):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::preconnectTo):
* UIProcess/WebPageProxy.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263057 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/Preconnect.mm [new file with mode: 0644]

index fce6451..6ca2268 100644 (file)
@@ -1,3 +1,23 @@
+2020-06-15  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI to preconnect to a server
+        https://bugs.webkit.org/show_bug.cgi?id=213109
+        <rdar://problem/64184412>
+
+        Reviewed by Geoff Garen.
+
+        Covered by API tests.
+
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _preconnectToServer:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::preconnectTo):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::preconnectTo):
+        * UIProcess/WebPageProxy.h:
+
 2020-06-15  Keith Miller  <keith_miller@apple.com>
 
         Signal handlers should have a two phase installation.
index 551168e..c0a84a1 100644 (file)
 // Test only. Should be called before any web content processes are launched.
 + (void)_forceGameControllerFramework WK_API_AVAILABLE(macos(10.13), ios(11.0));
 
-- (void)_preconnectToServer:(NSURL *)serverURL WK_API_DEPRECATED("If needed, SPI should be added to WKWebsiteDataStore", macos(10.13.4, WK_MAC_TBA), ios(11.3, WK_IOS_TBA));
+- (void)_preconnectToServer:(NSURL *)serverURL WK_API_DEPRECATED_WITH_REPLACEMENT("WKWebView._preconnectToServer", macos(10.13.4, WK_MAC_TBA), ios(11.3, WK_IOS_TBA));
 
 // Test only.
 - (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL)allows WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
index 555888a..12884ae 100644 (file)
@@ -2650,6 +2650,11 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
     });
 }
 
+- (void)_preconnectToServer:(NSURL *)url
+{
+    _page->preconnectTo(url);
+}
+
 - (id <_WKInputDelegate>)_inputDelegate
 {
     return _inputDelegate.getAutoreleased();
index 664e1b1..c7b3e9c 100644 (file)
@@ -349,6 +349,9 @@ for this property.
 
 - (void)_serviceWorkersEnabled:(void(^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_clearServiceWorkerEntitlementOverride:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
+- (void)_preconnectToServer:(NSURL *)serverURL WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @end
 
 #if TARGET_OS_IPHONE
index 471f166..4037cee 100644 (file)
@@ -4414,8 +4414,7 @@ void WebPageProxy::preconnectTo(const URL& url)
     if (!m_websiteDataStore->configuration().allowsServerPreconnect())
         return;
 
-    if (auto* networkProcess = m_process->processPool().networkProcess())
-        networkProcess->preconnectTo(sessionID(), identifier(), webPageID(), url, userAgent(), WebCore::StoredCredentialsPolicy::Use, m_isNavigatingToAppBoundDomain);
+    m_process->processPool().ensureNetworkProcess().preconnectTo(sessionID(), identifier(), webPageID(), url, userAgent(), WebCore::StoredCredentialsPolicy::Use, m_isNavigatingToAppBoundDomain);
 }
 
 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
index e1db2ce..2edf44f 100644 (file)
@@ -1782,6 +1782,8 @@ public:
 
     WebPopupMenuProxy* activePopupMenu() const { return m_activePopupMenu.get(); }
 
+    void preconnectTo(const URL&);
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     void platformInitialize();
@@ -1856,8 +1858,6 @@ private:
     void didFinishProgress();
     void setNetworkRequestsInProgress(bool);
 
-    void preconnectTo(const URL&);
-
     void didDestroyNavigation(uint64_t navigationID);
 
     void decidePolicyForNavigationAction(Ref<WebProcessProxy>&&, WebFrameProxy&, FrameInfoData&&, uint64_t navigationID, NavigationActionData&&, FrameInfoData&& originatingFrameInfo,
index b550b30..6c989a7 100644 (file)
@@ -1,3 +1,13 @@
+2020-06-15  Alex Christensen  <achristensen@webkit.org>
+
+        Add SPI to preconnect to a server
+        https://bugs.webkit.org/show_bug.cgi?id=213109
+        <rdar://problem/64184412>
+
+        Reviewed by Geoff Garen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
 2020-06-15  Keith Miller  <keith_miller@apple.com>
 
         Signal handlers should have a two phase installation.
index abfb840..57a2026 100644 (file)
                CEDA12412437C9FB00C28A9E /* editable-region-composited-and-non-composited-overlap.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEDA12402437C9EA00C28A9E /* editable-region-composited-and-non-composited-overlap.html */; };
                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */; };
                DF4B273921A47728009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF4B273821A47727009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm */; };
+               DFB8FF322492F52400F00B0D /* Preconnect.mm in Sources */ = {isa = PBXBuildFile; fileRef = DFB8FF312492F51A00F00B0D /* Preconnect.mm */; };
                E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; };
                E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; };
                E302BDAA2404B92400865277 /* CompactRefPtrTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E302BDA92404B92300865277 /* CompactRefPtrTuple.cpp */; };
                D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewGetContents.mm; sourceTree = "<group>"; };
                DC69AA621CF77C6500C6272F /* ScopedLambda.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedLambda.cpp; sourceTree = "<group>"; };
                DF4B273821A47727009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKNSDictionaryEmptyDictionaryCrash.mm; sourceTree = "<group>"; };
+               DFB8FF312492F51A00F00B0D /* Preconnect.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Preconnect.mm; sourceTree = "<group>"; };
                E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheDisableWithinResourceLoadDelegate.mm; sourceTree = "<group>"; };
                E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = MemoryCacheDisableWithinResourceLoadDelegate.html; sourceTree = "<group>"; };
                E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StopLoadingFromDidReceiveResponse.mm; sourceTree = "<group>"; };
                                516281262325C19100BB7E42 /* PDFSnapshot.mm */,
                                3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
                                83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
+                               DFB8FF312492F51A00F00B0D /* Preconnect.mm */,
                                C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
                                CD227E43211A4D5D00D285AF /* PreferredAudioBufferSize.mm */,
                                7C1AF7931E8DCBAB002645B9 /* PrepareForMoveToWindow.mm */,
                                7CCE7EA61A411A0F00447C4C /* PlatformUtilitiesMac.mm in Sources */,
                                7CCE7EA71A411A1300447C4C /* PlatformWebViewMac.mm in Sources */,
                                83BAEE8D1EF4625500DDE894 /* PluginLoadClientPolicies.mm in Sources */,
+                               DFB8FF322492F52400F00B0D /* Preconnect.mm in Sources */,
                                1D67BFDC2433E0A7006B5047 /* PreemptVideoFullscreen.mm in Sources */,
                                C15CBB3F23FB177A00300CC7 /* PreferenceChanges.mm in Sources */,
                                7CCE7F261A411AF600447C4C /* Preferences.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/Preconnect.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/Preconnect.mm
new file mode 100644 (file)
index 0000000..622719d
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "HTTPServer.h"
+#import "PlatformUtilities.h"
+#import "TestNavigationDelegate.h"
+#import "Utilities.h"
+#import <WebKit/WKWebViewPrivate.h>
+#import <wtf/RetainPtr.h>
+
+namespace TestWebKitAPI {
+
+TEST(Preconnect, HTTP)
+{
+    bool connected = false;
+    bool requested = false;
+    HTTPServer server([&] (Connection connection) {
+        connected = true;
+        connection.receiveHTTPRequest([&](Vector<char>&&) {
+            requested = true;
+        });
+    });
+    auto webView = adoptNS([WKWebView new]);
+    [webView _preconnectToServer:server.request().URL];
+    Util::run(&connected);
+    Util::spinRunLoop(10);
+    EXPECT_FALSE(requested);
+    [webView loadRequest:server.request()];
+    Util::run(&requested);
+}
+
+// Mojave CFNetwork _preconnect SPI seems to have a bug causing this to time out.
+// That's no problem, because this is a test for SPI only to be used on later OS versions.
+#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
+
+TEST(Preconnect, HTTPS)
+{
+    bool connected = false;
+    bool requested = false;
+    __block bool receivedChallenge = false;
+    HTTPServer server([&] (Connection connection) {
+        connected = true;
+        connection.receiveHTTPRequest([&](Vector<char>&&) {
+            requested = true;
+        });
+    }, HTTPServer::Protocol::Https);
+    auto webView = adoptNS([WKWebView new]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+        receivedChallenge = true;
+        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    }];
+    [webView _preconnectToServer:server.request().URL];
+    Util::run(&connected);
+    Util::spinRunLoop(10);
+    EXPECT_FALSE(receivedChallenge);
+    EXPECT_FALSE(requested);
+    [webView loadRequest:server.request()];
+    Util::run(&requested);
+    EXPECT_TRUE(receivedChallenge);
+}
+
+#endif
+
+}