Title: [290722] trunk
Revision
290722
Author
[email protected]
Date
2022-03-02 00:09:08 -0800 (Wed, 02 Mar 2022)

Log Message

Add SPI _WKDataTask
https://bugs.webkit.org/show_bug.cgi?id=237234

Patch by Alex Christensen <[email protected]> on 2022-03-02
Reviewed by Tim Horton.

Source/WebKit:

When I added WKWebView._requestResource:completionHandler: I overlooked a few things.
First, it is unable to support HTTPS because I didn't hook up authentication challenge handling to it.
Second, it is unable to have a maximum accepted response length, which is a requirement for an adopter.
To make these possible, I made _WKDataTask which is related to WKDownload and NSURLSessionDataTask.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::dataTaskWithRequest):
(WebKit::NetworkProcess::cancelDataTask):
(WebKit::NetworkProcess::requestResource): Deleted.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::dataTaskWithRequest):
(WebKit::NetworkSession::cancelDataTask):
(WebKit::NetworkSession::requestResource): Deleted.
* NetworkProcess/cocoa/NetworkSessionCocoa.h:
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(WebKit::NetworkSessionCocoa::dataTaskWithRequest):
(WebKit::NetworkSessionCocoa::cancelDataTask):
(WebKit::NetworkSessionCocoa::removeDataTask):
(WebKit::NetworkSessionCocoa::requestResource): Deleted.
* NetworkProcess/cocoa/WKURLSessionTaskDelegate.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
* NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm: Added.
(-[WKURLSessionTaskDelegate initWithIdentifier:session:]):
(-[WKURLSessionTaskDelegate connection]):
(-[WKURLSessionTaskDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
(-[WKURLSessionTaskDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
(-[WKURLSessionTaskDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
(-[WKURLSessionTaskDelegate URLSession:dataTask:didReceiveData:]):
(-[WKURLSessionTaskDelegate URLSession:task:didCompleteWithError:]):
* Scripts/webkit/messages.py:
(types_that_cannot_be_forward_declared):
* Shared/API/APIObject.h:
* Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h:
* Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.mm:
(WebKit::fromAuthenticationChallengeDisposition):
* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* Shared/DataTaskIdentifier.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
* Sources.txt:
* SourcesCocoa.txt:
* UIProcess/API/APIDataTask.cpp: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
(API::DataTask::setClient):
(API::DataTask::cancel):
(API::DataTask::DataTask):
* UIProcess/API/APIDataTask.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
(API::DataTask::create):
(API::DataTask::page):
(API::DataTask::client const):
* UIProcess/API/APIDataTaskClient.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
(API::DataTaskClient::create):
(API::DataTaskClient::~DataTaskClient):
(API::DataTaskClient::didReceiveChallenge const):
(API::DataTaskClient::willPerformHTTPRedirection const):
(API::DataTaskClient::didReceiveResponse const):
(API::DataTaskClient::didReceiveData const):
(API::DataTaskClient::didCompleteWithError const):
* UIProcess/API/APIInspectorExtensionClient.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _dataTaskWithRequest:completionHandler:]):
(-[WKWebView _requestResource:completionHandler:]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/API/Cocoa/_WKDataTask.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
* UIProcess/API/Cocoa/_WKDataTask.mm: Added.
(-[_WKDataTask cancel]):
(-[_WKDataTask webView]):
(-[_WKDataTask delegate]):
(-[_WKDataTask setDelegate:]):
(-[_WKDataTask dealloc]):
(-[_WKDataTask _apiObject]):
* UIProcess/API/Cocoa/_WKDataTaskDelegate.h: Added.
* UIProcess/API/Cocoa/_WKDataTaskInternal.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::dataTaskWithRequest):
(WebKit::NetworkProcessProxy::dataTaskReceivedChallenge):
(WebKit::NetworkProcessProxy::dataTaskWillPerformHTTPRedirection):
(WebKit::NetworkProcessProxy::dataTaskDidReceiveResponse):
(WebKit::NetworkProcessProxy::dataTaskDidReceiveData):
(WebKit::NetworkProcessProxy::dataTaskDidCompleteWithError):
(WebKit::NetworkProcessProxy::requestResource): Deleted.
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::dataTaskWithRequest):
(WebKit::WebPageProxy::requestResource): Deleted.
* UIProcess/WebPageProxy.h:
* WebKit.xcodeproj/project.pbxproj:

Source/WTF:

* wtf/PlatformHave.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm:
(-[TestDataTaskDelegate dataTask:didReceiveAuthenticationChallenge:completionHandler:]):
(-[TestDataTaskDelegate dataTask:didReceiveResponse:decisionHandler:]):
(-[TestDataTaskDelegate dataTask:didReceiveData:]):
(-[TestDataTaskDelegate dataTask:didCompleteWithError:]):
(TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (290721 => 290722)


--- trunk/Source/WTF/ChangeLog	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WTF/ChangeLog	2022-03-02 08:09:08 UTC (rev 290722)
@@ -1,3 +1,12 @@
+2022-03-02  Alex Christensen  <[email protected]>
+
+        Add SPI _WKDataTask
+        https://bugs.webkit.org/show_bug.cgi?id=237234
+
+        Reviewed by Tim Horton.
+
+        * wtf/PlatformHave.h:
+
 2022-03-01  Fujii Hironori  <[email protected]>
 
         WTF::SentinelLinkedList::iterator should have operator++ for range-for loop

Modified: trunk/Source/WTF/wtf/PlatformHave.h (290721 => 290722)


--- trunk/Source/WTF/wtf/PlatformHave.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WTF/wtf/PlatformHave.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -999,6 +999,7 @@
     || (PLATFORM(APPLETV) && __TV_OS_VERSION_MIN_REQUIRED >= 150000)
 #define HAVE_CFNETWORK_NSURLSESSION_ATTRIBUTED_BUNDLE_IDENTIFIER 1
 #define HAVE_CFNETWORK_NSURLSESSION_HSTS_WITH_UNTRUSTED_ROOT 1
+#define HAVE_NSURLSESSION_TASK_DELEGATE 1
 #define HAVE_AUDIO_OBJECT_PROPERTY_ELEMENT_MAIN 1
 #define HAVE_IMAGE_RESTRICTED_DECODING 1
 #define HAVE_XPC_CONNECTION_COPY_INVALIDATION_REASON 1

Modified: trunk/Source/WebKit/ChangeLog (290721 => 290722)


--- trunk/Source/WebKit/ChangeLog	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/ChangeLog	2022-03-02 08:09:08 UTC (rev 290722)
@@ -1,3 +1,98 @@
+2022-03-02  Alex Christensen  <[email protected]>
+
+        Add SPI _WKDataTask
+        https://bugs.webkit.org/show_bug.cgi?id=237234
+
+        Reviewed by Tim Horton.
+
+        When I added WKWebView._requestResource:completionHandler: I overlooked a few things.
+        First, it is unable to support HTTPS because I didn't hook up authentication challenge handling to it.
+        Second, it is unable to have a maximum accepted response length, which is a requirement for an adopter.
+        To make these possible, I made _WKDataTask which is related to WKDownload and NSURLSessionDataTask.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::dataTaskWithRequest):
+        (WebKit::NetworkProcess::cancelDataTask):
+        (WebKit::NetworkProcess::requestResource): Deleted.
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::dataTaskWithRequest):
+        (WebKit::NetworkSession::cancelDataTask):
+        (WebKit::NetworkSession::requestResource): Deleted.
+        * NetworkProcess/cocoa/NetworkSessionCocoa.h:
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (WebKit::NetworkSessionCocoa::dataTaskWithRequest):
+        (WebKit::NetworkSessionCocoa::cancelDataTask):
+        (WebKit::NetworkSessionCocoa::removeDataTask):
+        (WebKit::NetworkSessionCocoa::requestResource): Deleted.
+        * NetworkProcess/cocoa/WKURLSessionTaskDelegate.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
+        * NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm: Added.
+        (-[WKURLSessionTaskDelegate initWithIdentifier:session:]):
+        (-[WKURLSessionTaskDelegate connection]):
+        (-[WKURLSessionTaskDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
+        (-[WKURLSessionTaskDelegate URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:]):
+        (-[WKURLSessionTaskDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):
+        (-[WKURLSessionTaskDelegate URLSession:dataTask:didReceiveData:]):
+        (-[WKURLSessionTaskDelegate URLSession:task:didCompleteWithError:]):
+        * Scripts/webkit/messages.py:
+        (types_that_cannot_be_forward_declared):
+        * Shared/API/APIObject.h:
+        * Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h:
+        * Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.mm:
+        (WebKit::fromAuthenticationChallengeDisposition):
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * Shared/DataTaskIdentifier.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * UIProcess/API/APIDataTask.cpp: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
+        (API::DataTask::setClient):
+        (API::DataTask::cancel):
+        (API::DataTask::DataTask):
+        * UIProcess/API/APIDataTask.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
+        (API::DataTask::create):
+        (API::DataTask::page):
+        (API::DataTask::client const):
+        * UIProcess/API/APIDataTaskClient.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
+        (API::DataTaskClient::create):
+        (API::DataTaskClient::~DataTaskClient):
+        (API::DataTaskClient::didReceiveChallenge const):
+        (API::DataTaskClient::willPerformHTTPRedirection const):
+        (API::DataTaskClient::didReceiveResponse const):
+        (API::DataTaskClient::didReceiveData const):
+        (API::DataTaskClient::didCompleteWithError const):
+        * UIProcess/API/APIInspectorExtensionClient.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _dataTaskWithRequest:completionHandler:]):
+        (-[WKWebView _requestResource:completionHandler:]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/API/Cocoa/_WKDataTask.h: Copied from Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h.
+        * UIProcess/API/Cocoa/_WKDataTask.mm: Added.
+        (-[_WKDataTask cancel]):
+        (-[_WKDataTask webView]):
+        (-[_WKDataTask delegate]):
+        (-[_WKDataTask setDelegate:]):
+        (-[_WKDataTask dealloc]):
+        (-[_WKDataTask _apiObject]):
+        * UIProcess/API/Cocoa/_WKDataTaskDelegate.h: Added.
+        * UIProcess/API/Cocoa/_WKDataTaskInternal.h: Copied from Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h.
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::dataTaskWithRequest):
+        (WebKit::NetworkProcessProxy::dataTaskReceivedChallenge):
+        (WebKit::NetworkProcessProxy::dataTaskWillPerformHTTPRedirection):
+        (WebKit::NetworkProcessProxy::dataTaskDidReceiveResponse):
+        (WebKit::NetworkProcessProxy::dataTaskDidReceiveData):
+        (WebKit::NetworkProcessProxy::dataTaskDidCompleteWithError):
+        (WebKit::NetworkProcessProxy::requestResource): Deleted.
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::dataTaskWithRequest):
+        (WebKit::WebPageProxy::requestResource): Deleted.
+        * UIProcess/WebPageProxy.h:
+        * WebKit.xcodeproj/project.pbxproj:
+
 2022-03-01  Youenn Fablet  <[email protected]>
 
         Remove RemoteVideoSample support from ImageTransferSessionVT

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-02 08:09:08 UTC (rev 290722)
@@ -1999,13 +1999,16 @@
     }, destinationID);
 }
 
-void NetworkProcess::requestResource(WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, IPC::FormDataReference&& httpBody, CompletionHandler<void(IPC::DataReference, WebCore::ResourceResponse, WebCore::ResourceError)>&& completionHandler)
+void NetworkProcess::dataTaskWithRequest(WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, IPC::FormDataReference&& httpBody, CompletionHandler<void(DataTaskIdentifier)>&& completionHandler)
 {
     request.setHTTPBody(httpBody.takeData());
+    networkSession(sessionID)->dataTaskWithRequest(pageID, WTFMove(request), WTFMove(completionHandler));
+}
+
+void NetworkProcess::cancelDataTask(DataTaskIdentifier identifier, PAL::SessionID sessionID)
+{
     if (auto* session = networkSession(sessionID))
-        session->requestResource(pageID, WTFMove(request), WTFMove(completionHandler));
-    else
-        completionHandler({ }, { }, { });
+        session->cancelDataTask(identifier);
 }
 
 void NetworkProcess::setCacheModelSynchronouslyForTesting(CacheModel cacheModel, CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -28,6 +28,7 @@
 #include "AppPrivacyReport.h"
 #include "AuxiliaryProcess.h"
 #include "CacheModel.h"
+#include "DataTaskIdentifier.h"
 #include "DownloadID.h"
 #include "DownloadManager.h"
 #include "LocalStorageDatabaseTracker.h"
@@ -432,7 +433,8 @@
     void publishDownloadProgress(DownloadID, const URL&, SandboxExtension::Handle&&);
 #endif
     void continueWillSendRequest(DownloadID, WebCore::ResourceRequest&&);
-    void requestResource(WebPageProxyIdentifier, PAL::SessionID, WebCore::ResourceRequest&&, IPC::FormDataReference&&, CompletionHandler<void(IPC::DataReference, WebCore::ResourceResponse, WebCore::ResourceError)>&&);
+    void dataTaskWithRequest(WebPageProxyIdentifier, PAL::SessionID, WebCore::ResourceRequest&&, IPC::FormDataReference&&, CompletionHandler<void(DataTaskIdentifier)>&&);
+    void cancelDataTask(DataTaskIdentifier, PAL::SessionID);
     void applicationDidEnterBackground();
     void applicationWillEnterForeground();
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in	2022-03-02 08:09:08 UTC (rev 290722)
@@ -53,7 +53,8 @@
 #if PLATFORM(COCOA)
     PublishDownloadProgress(WebKit::DownloadID downloadID, URL url, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
 #endif
-    RequestResource(WebKit::WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest request, IPC::FormDataReference requestBody) -> (IPC::DataReference data, WebCore::ResourceResponse response, WebCore::ResourceError error) Async
+    DataTaskWithRequest(WebKit::WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest request, IPC::FormDataReference requestBody) -> (WebKit::DataTaskIdentifier taskIdentifier) Async
+    CancelDataTask(WebKit::DataTaskIdentifier taskIdentifier, PAL::SessionID sessionID)
     ApplicationDidEnterBackground()
     ApplicationWillEnterForeground()
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -27,6 +27,7 @@
 
 #include "AppPrivacyReport.h"
 #include "DataReference.h"
+#include "DataTaskIdentifier.h"
 #include "NavigatingToAppBoundDomain.h"
 #include "NetworkNotificationManager.h"
 #include "NetworkResourceLoadIdentifier.h"
@@ -232,7 +233,8 @@
 
     virtual void removeNetworkWebsiteData(std::optional<WallTime>, std::optional<HashSet<WebCore::RegistrableDomain>>&&, CompletionHandler<void()>&& completionHandler) { completionHandler(); }
 
-    virtual void requestResource(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&) { }
+    virtual void dataTaskWithRequest(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(DataTaskIdentifier)>&&) { }
+    virtual void cancelDataTask(DataTaskIdentifier) { }
     virtual void addWebPageNetworkParameters(WebPageProxyIdentifier, WebPageNetworkParameters&&) { }
     virtual void removeWebPageNetworkParameters(WebPageProxyIdentifier) { }
     virtual size_t countNonDefaultSessionSets() const { return 0; }

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -142,6 +142,8 @@
 
     void removeNetworkWebsiteData(std::optional<WallTime>, std::optional<HashSet<WebCore::RegistrableDomain>>&&, CompletionHandler<void()>&&) override;
 
+    void removeDataTask(DataTaskIdentifier);
+
 private:
     void invalidateAndCancel() override;
     void clearCredentials() override;
@@ -162,7 +164,8 @@
     void removeWebSocketTask(SessionSet&, WebSocketTask&) final;
 #endif
 
-    void requestResource(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&) final;
+    void dataTaskWithRequest(WebPageProxyIdentifier, WebCore::ResourceRequest&&, CompletionHandler<void(DataTaskIdentifier)>&&) final;
+    void cancelDataTask(DataTaskIdentifier) final;
     void addWebPageNetworkParameters(WebPageProxyIdentifier, WebPageNetworkParameters&&) final;
     void removeWebPageNetworkParameters(WebPageProxyIdentifier) final;
     size_t countNonDefaultSessionSets() const final;
@@ -188,6 +191,7 @@
     bool m_fastServerTrustEvaluationEnabled { false };
     String m_dataConnectionServiceType;
     bool m_preventsSystemHTTPProxyAuthentication { false };
+    HashMap<DataTaskIdentifier, RetainPtr<NSURLSessionDataTask>> m_dataTasksForAPI;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (290721 => 290722)


--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -37,6 +37,7 @@
 #import "NetworkProcess.h"
 #import "NetworkSessionCreationParameters.h"
 #import "PrivateRelayed.h"
+#import "WKURLSessionTaskDelegate.h"
 #import "WebPageNetworkParameters.h"
 #import "WebSocketTask.h"
 #import <Foundation/NSURLSession.h>
@@ -1771,16 +1772,32 @@
     m_attributedBundleIdentifierFromPageIdentifiers.add(pageID, parameters.attributedBundleIdentifier());
 }
 
-void NetworkSessionCocoa::requestResource(WebPageProxyIdentifier pageID, WebCore::ResourceRequest&& request, CompletionHandler<void(const IPC::DataReference&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
+void NetworkSessionCocoa::dataTaskWithRequest(WebPageProxyIdentifier pageID, WebCore::ResourceRequest&& request, CompletionHandler<void(DataTaskIdentifier)>&& completionHandler)
 {
+    auto identifier = DataTaskIdentifier::generate();
+    auto nsRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::UpdateHTTPBody);
     auto session = sessionWrapperForTask(pageID, request, WebCore::StoredCredentialsPolicy::Use, std::nullopt).session;
-    auto nsRequest = request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::UpdateHTTPBody);
-    auto completionBlock = makeBlockPtr([completionHandler = WTFMove(completionHandler)] (NSData *data, NSURLResponse *response, NSError *error) mutable {
-        completionHandler(IPC::DataReference { static_cast<const uint8_t*>(data.bytes), data.length }, WebCore::ResourceResponse { response }, WebCore::ResourceError { error });
-    });
-    [[session dataTaskWithRequest:nsRequest completionHandler:completionBlock.get()] resume];
+    auto task = [session dataTaskWithRequest:nsRequest];
+    auto delegate = adoptNS([[WKURLSessionTaskDelegate alloc] initWithIdentifier:identifier session:*this]);
+#if HAVE(NSURLSESSION_TASK_DELEGATE)
+    task.delegate = delegate.get();
+#endif
+    auto addResult = m_dataTasksForAPI.add(identifier, task);
+    RELEASE_ASSERT(addResult.isNewEntry);
+    [task resume];
+    completionHandler(identifier);
 }
 
+void NetworkSessionCocoa::cancelDataTask(DataTaskIdentifier identifier)
+{
+    [m_dataTasksForAPI.take(identifier) cancel];
+}
+
+void NetworkSessionCocoa::removeDataTask(DataTaskIdentifier identifier)
+{
+    m_dataTasksForAPI.remove(identifier);
+}
+
 void NetworkSessionCocoa::removeWebPageNetworkParameters(WebPageProxyIdentifier pageID)
 {
     m_perPageSessionSets.remove(pageID);

Copied: trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.h (from rev 290721, trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h) (0 => 290722)


--- trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#import "DataTaskIdentifier.h"
+
+namespace WebKit {
+class NetworkSessionCocoa;
+}
+
+@protocol NSURLSessionTaskDelegate;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface WKURLSessionTaskDelegate : NSObject<NSURLSessionTaskDelegate>
+- (instancetype)initWithIdentifier:(WebKit::DataTaskIdentifier)identifier session:(WebKit::NetworkSessionCocoa&)session;
+@end
+
+NS_ASSUME_NONNULL_END

Added: trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm (0 => 290722)


--- trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 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 "WKURLSessionTaskDelegate.h"
+
+#import "AuthenticationChallengeDispositionCocoa.h"
+#import "Connection.h"
+#import "NetworkProcess.h"
+#import "NetworkProcessProxyMessages.h"
+#import "NetworkSessionCocoa.h"
+#import "WebCoreArgumentCoders.h"
+#import <Foundation/NSURLSession.h>
+#import <WebCore/AuthenticationChallenge.h>
+#import <WebCore/Credential.h>
+#import <WebCore/ResourceError.h>
+#import <WebCore/ResourceRequest.h>
+#import <WebCore/ResourceResponse.h>
+#import <wtf/BlockPtr.h>
+
+@implementation WKURLSessionTaskDelegate {
+    WebKit::DataTaskIdentifier _identifier;
+    WeakPtr<WebKit::NetworkSessionCocoa> _session;
+}
+
+- (instancetype)initWithIdentifier:(WebKit::DataTaskIdentifier)identifier session:(WebKit::NetworkSessionCocoa&)session
+{
+    if (!(self = [super init]))
+        return nil;
+    _identifier = identifier;
+    _session = WeakPtr { session };
+    return self;
+}
+
+- (IPC::Connection*)connection
+{
+    if (!_session)
+        return nil;
+    return _session->networkProcess().parentProcessConnection();
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
+{
+    auto* connection = [self connection];
+    if (!connection)
+        return completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
+    connection->sendWithAsyncReply(Messages::NetworkProcessProxy::DataTaskReceivedChallenge(_identifier, challenge), [completionHandler = makeBlockPtr(completionHandler)](WebKit::AuthenticationChallengeDisposition disposition, WebCore::Credential&& credential) {
+        completionHandler(fromAuthenticationChallengeDisposition(disposition), credential.nsCredential());
+    });
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler
+{
+    auto* connection = [self connection];
+    if (!connection)
+        return completionHandler(nil);
+    connection->sendWithAsyncReply(Messages::NetworkProcessProxy::DataTaskWillPerformHTTPRedirection(_identifier, response, request), [completionHandler = makeBlockPtr(completionHandler), request = RetainPtr { request }] (bool allowed) {
+        completionHandler(allowed ? request.get() : nil);
+    });
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
+{
+    auto* connection = [self connection];
+    if (!connection)
+        return completionHandler(NSURLSessionResponseCancel);
+    connection->sendWithAsyncReply(Messages::NetworkProcessProxy::DataTaskDidReceiveResponse(_identifier, response), [completionHandler = makeBlockPtr(completionHandler)] (bool allowed) {
+        completionHandler(allowed ? NSURLSessionResponseAllow : NSURLSessionResponseCancel);
+    });
+}
+
+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
+{
+    auto* connection = [self connection];
+    if (!connection)
+        return;
+    connection->send(Messages::NetworkProcessProxy::DataTaskDidReceiveData(_identifier, { reinterpret_cast<const uint8_t*>(data.bytes), data.length }), 0);
+}
+
+- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
+{
+    auto* connection = [self connection];
+    if (!connection)
+        return;
+    connection->send(Messages::NetworkProcessProxy::DataTaskDidCompleteWithError(_identifier, error), 0);
+    if (_session)
+        _session->removeDataTask(_identifier);
+}
+
+@end

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (290721 => 290722)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2022-03-02 08:09:08 UTC (rev 290722)
@@ -319,6 +319,7 @@
         'WebKit::AudioMediaStreamTrackRendererInternalUnitIdentifier',
         'WebKit::AuthenticationChallengeIdentifier',
         'WebKit::ContentWorldIdentifier',
+        'WebKit::DataTaskIdentifier',
         'WebKit::DisplayLinkObserverID',
         'WebKit::DownloadID',
         'WebKit::FileSystemStorageError',

Modified: trunk/Source/WebKit/Shared/API/APIObject.h (290721 => 290722)


--- trunk/Source/WebKit/Shared/API/APIObject.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Shared/API/APIObject.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -116,6 +116,7 @@
         ContextMenuListener,
         CustomHeaderFields,
         InternalDebugFeature,
+        DataTask,
         DebuggableInfo,
         Download,
         ExperimentalFeature,
@@ -364,6 +365,7 @@
         API::Object::Type::ContextMenuListener,
         API::Object::Type::CustomHeaderFields,
         API::Object::Type::InternalDebugFeature,
+        API::Object::Type::DataTask,
         API::Object::Type::DebuggableInfo,
         API::Object::Type::Download,
         API::Object::Type::ExperimentalFeature,

Modified: trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h (290721 => 290722)


--- trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -31,5 +31,6 @@
 namespace WebKit {
 
 AuthenticationChallengeDisposition toAuthenticationChallengeDisposition(NSURLSessionAuthChallengeDisposition);
+NSURLSessionAuthChallengeDisposition fromAuthenticationChallengeDisposition(AuthenticationChallengeDisposition);
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.mm (290721 => 290722)


--- trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -43,4 +43,19 @@
     [NSException raise:NSInvalidArgumentException format:@"Invalid NSURLSessionAuthChallengeDisposition (%ld)", (long)disposition];
 }
 
+NSURLSessionAuthChallengeDisposition fromAuthenticationChallengeDisposition(AuthenticationChallengeDisposition disposition)
+{
+    switch (disposition) {
+    case AuthenticationChallengeDisposition::UseCredential:
+        return NSURLSessionAuthChallengeUseCredential;
+    case AuthenticationChallengeDisposition::PerformDefaultHandling:
+        return NSURLSessionAuthChallengePerformDefaultHandling;
+    case AuthenticationChallengeDisposition::Cancel:
+        return NSURLSessionAuthChallengeCancelAuthenticationChallenge;
+    case AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue:
+        return NSURLSessionAuthChallengeRejectProtectionSpace;
+    }
+    [NSException raise:NSInvalidArgumentException format:@"Invalid AuthenticationChallengeDisposition (%ld)", (long)disposition];
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/Shared/Cocoa/APIObject.mm (290721 => 290722)


--- trunk/Source/WebKit/Shared/Cocoa/APIObject.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Shared/Cocoa/APIObject.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -74,6 +74,7 @@
 #import "_WKAutomationSessionInternal.h"
 #import "_WKContentRuleListActionInternal.h"
 #import "_WKCustomHeaderFieldsInternal.h"
+#import "_WKDataTaskInternal.h"
 #import "_WKExperimentalFeatureInternal.h"
 #import "_WKFrameHandleInternal.h"
 #import "_WKFrameTreeNodeInternal.h"
@@ -219,6 +220,10 @@
         wrapper = [WKNSData alloc];
         break;
 
+    case Type::DataTask:
+        wrapper = [_WKDataTask alloc];
+        break;
+
     case Type::InternalDebugFeature:
         wrapper = [_WKInternalDebugFeature alloc];
         break;

Copied: trunk/Source/WebKit/Shared/DataTaskIdentifier.h (from rev 290721, trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h) (0 => 290722)


--- trunk/Source/WebKit/Shared/DataTaskIdentifier.h	                        (rev 0)
+++ trunk/Source/WebKit/Shared/DataTaskIdentifier.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <wtf/ObjectIdentifier.h>
+
+namespace WebKit {
+
+enum DataTaskIdentifierType { };
+using DataTaskIdentifier = ObjectIdentifier<DataTaskIdentifierType>;
+
+}

Modified: trunk/Source/WebKit/Sources.txt (290721 => 290722)


--- trunk/Source/WebKit/Sources.txt	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/Sources.txt	2022-03-02 08:09:08 UTC (rev 290722)
@@ -475,6 +475,7 @@
 UIProcess/API/APIContentRuleListStore.cpp
 UIProcess/API/APIContentWorld.cpp
 UIProcess/API/APIContextMenuElementInfo.cpp
+UIProcess/API/APIDataTask.cpp
 UIProcess/API/APIDebuggableInfo.cpp
 UIProcess/API/APIExperimentalFeature.cpp
 UIProcess/API/APIFrameInfo.cpp

Modified: trunk/Source/WebKit/SourcesCocoa.txt (290721 => 290722)


--- trunk/Source/WebKit/SourcesCocoa.txt	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/SourcesCocoa.txt	2022-03-02 08:09:08 UTC (rev 290722)
@@ -28,6 +28,7 @@
 NetworkProcess/cocoa/NetworkDataTaskCocoa.mm
 NetworkProcess/cocoa/NetworkProcessCocoa.mm
 NetworkProcess/cocoa/NetworkSessionCocoa.mm
+NetworkProcess/cocoa/WKURLSessionTaskDelegate.mm
 
 NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp
 
@@ -279,6 +280,7 @@
 UIProcess/API/Cocoa/_WKContentRuleListAction.mm
 UIProcess/API/Cocoa/_WKContextMenuElementInfo.mm
 UIProcess/API/Cocoa/_WKCustomHeaderFields.mm @no-unify
+UIProcess/API/Cocoa/_WKDataTask.mm
 UIProcess/API/Cocoa/_WKDownload.mm
 UIProcess/API/Cocoa/_WKElementAction.mm
 UIProcess/API/Cocoa/_WKErrorRecoveryAttempting.mm

Copied: trunk/Source/WebKit/UIProcess/API/APIDataTask.cpp (from rev 290721, trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h) (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/APIDataTask.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/APIDataTask.cpp	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include "config.h"
+#include "APIDataTask.h"
+
+#include "APIDataTaskClient.h"
+#include "NetworkProcessProxy.h"
+#include "WebPageProxy.h"
+
+namespace API {
+
+DataTask::~DataTask() = default;
+
+void DataTask::setClient(Ref<DataTaskClient>&& client)
+{
+    m_client = WTFMove(client);
+}
+
+void DataTask::cancel()
+{
+    if (m_networkProcess)
+        m_networkProcess->cancelDataTask(m_identifier, m_sessionID);
+}
+
+DataTask::DataTask(WebKit::DataTaskIdentifier identifier, WeakPtr<WebKit::WebPageProxy>&& page, WTF::URL&& originalURL)
+    : m_identifier(identifier)
+    , m_page(WTFMove(page))
+    , m_originalURL(WTFMove(originalURL))
+    , m_networkProcess(m_page->websiteDataStore().networkProcess())
+    , m_sessionID(m_page->sessionID())
+    , m_client(DataTaskClient::create()) { }
+
+} // namespace API

Copied: trunk/Source/WebKit/UIProcess/API/APIDataTask.h (from rev 290721, trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h) (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/APIDataTask.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/APIDataTask.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include "APIObject.h"
+#include "DataTaskIdentifier.h"
+#include <pal/SessionID.h>
+#include <wtf/URL.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebKit {
+class NetworkProcessProxy;
+class WebPageProxy;
+}
+
+namespace API {
+
+class DataTaskClient;
+
+class DataTask : public API::ObjectImpl<API::Object::Type::DataTask> {
+public:
+
+    template<typename... Args> static Ref<DataTask> create(Args&&... args)
+    {
+        return adoptRef(*new DataTask(std::forward<Args>(args)...));
+    }
+    ~DataTask();
+
+    void cancel();
+
+    WebKit::WebPageProxy* page() { return m_page.get(); }
+    const WTF::URL& originalURL() const { return m_originalURL; }
+    const DataTaskClient& client() const { return m_client.get(); }
+    void setClient(Ref<DataTaskClient>&&);
+
+private:
+    DataTask(WebKit::DataTaskIdentifier, WeakPtr<WebKit::WebPageProxy>&&, WTF::URL&&);
+
+    WebKit::DataTaskIdentifier m_identifier;
+    WeakPtr<WebKit::WebPageProxy> m_page;
+    WTF::URL m_originalURL;
+    WeakPtr<WebKit::NetworkProcessProxy> m_networkProcess;
+    PAL::SessionID m_sessionID;
+    Ref<DataTaskClient> m_client;
+};
+
+} // namespace API

Copied: trunk/Source/WebKit/UIProcess/API/APIDataTaskClient.h (from rev 290721, trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h) (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/APIDataTaskClient.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/APIDataTaskClient.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include "AuthenticationChallengeDisposition.h"
+#include "AuthenticationChallengeProxy.h"
+#include <wtf/CompletionHandler.h>
+
+namespace WebCore {
+class Credential;
+class ResourceError;
+class ResourceRequest;
+class ResourceResponse;
+}
+
+namespace API {
+
+class Data;
+
+class DataTaskClient : public RefCounted<DataTaskClient> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Ref<DataTaskClient> create() { return adoptRef(*new DataTaskClient); }
+    virtual ~DataTaskClient() { }
+
+    virtual void didReceiveChallenge(DataTask&, WebCore::AuthenticationChallenge&&, CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, WebCore::Credential&&)>&& completionHandler) const { completionHandler(WebKit::AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue, { }); }
+    virtual void willPerformHTTPRedirection(DataTask&, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, CompletionHandler<void(bool)>&& completionHandler) const { completionHandler(true); }
+    virtual void didReceiveResponse(DataTask&, WebCore::ResourceResponse&&, CompletionHandler<void(bool)>&& completionHandler) const { completionHandler(true); }
+    virtual void didReceiveData(DataTask&, const IPC::DataReference&) const { }
+    virtual void didCompleteWithError(DataTask&, WebCore::ResourceError&&) const { }
+};
+
+} // namespace API

Modified: trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "InspectorExtensionTypes.h"
+#include <WebCore/FrameIdentifier.h>
 #include <wtf/Forward.h>
 
 namespace API {

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "WKWebViewInternal.h"
 
+#import "APIDataTask.h"
 #import "APIFormClient.h"
 #import "APIFrameTreeNode.h"
 #import "APIPageConfiguration.h"
@@ -99,6 +100,7 @@
 #import "_WKActivatedElementInfoInternal.h"
 #import "_WKAppHighlightDelegate.h"
 #import "_WKAppHighlightInternal.h"
+#import "_WKDataTaskInternal.h"
 #import "_WKDiagnosticLoggingDelegate.h"
 #import "_WKFindDelegate.h"
 #import "_WKFrameHandleInternal.h"
@@ -2224,12 +2226,10 @@
 #endif
 }
 
-- (void)_requestResource:(NSURLRequest *)request completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *))completionHandler
+- (void)_dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void(^)(_WKDataTask *))completionHandler
 {
-    _page->requestResource(request, [completionHandler = makeBlockPtr(completionHandler)] (Ref<WebCore::SharedBuffer>&& buffer, WebCore::ResourceResponse&& response, WebCore::ResourceError&& error) {
-        if (error.isNull())
-            return completionHandler(buffer->createNSData().get(), response.nsURLResponse(), nil);
-        completionHandler(nil, nil, error.nsError());
+    _page->dataTaskWithRequest(request, [completionHandler = makeBlockPtr(completionHandler)] (Ref<API::DataTask>&& task) {
+        completionHandler(wrapper(task));
     });
 }
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -122,6 +122,7 @@
 @class WKFrameInfo;
 @class WKWebpagePreferences;
 @class _WKApplicationManifest;
+@class _WKDataTask;
 @class _WKFrameHandle;
 @class _WKFrameTreeNode;
 @class _WKHitTestResult;
@@ -427,7 +428,7 @@
 
 - (void)_startImageAnalysis:(NSString *)identifier WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
-- (void)_requestResource:(NSURLRequest *)request completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void(^)(_WKDataTask *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 typedef NS_ENUM(NSInteger, WKDisplayCaptureState) {
     WKDisplayCaptureStateNone,

Copied: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.h (from rev 290721, trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h) (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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 <WebKit/WKFoundation.h>
+
+@protocol _WKDataTaskDelegate;
+
+NS_ASSUME_NONNULL_BEGIN
+
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKDataTask : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
++ (instancetype)new NS_UNAVAILABLE;
+
+// Delegate is strongly referenced until the task completes, after which it is
+// reset to `nil`.
+@property (nonatomic, strong) id <_WKDataTaskDelegate> delegate;
+@property (nonatomic, readonly, weak) WKWebView *webView;
+- (void)cancel;
+
+@end
+
+NS_ASSUME_NONNULL_END

Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.mm (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.mm	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTask.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2022 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 "_WKDataTaskInternal.h"
+
+#import "APIDataTask.h"
+#import "APIDataTaskClient.h"
+#import "AuthenticationChallengeDispositionCocoa.h"
+#import "CompletionHandlerCallChecker.h"
+#import "WebPageProxy.h"
+#import "_WKDataTaskDelegate.h"
+#import <WebCore/AuthenticationMac.h>
+#import <WebCore/Credential.h>
+
+class WKDataTaskClient final : public API::DataTaskClient {
+public:
+    static Ref<WKDataTaskClient> create(id <_WKDataTaskDelegate> delegate) { return adoptRef(*new WKDataTaskClient(delegate)); }
+private:
+    explicit WKDataTaskClient(id <_WKDataTaskDelegate> delegate)
+        : m_delegate(delegate)
+        , m_respondsToDidReceiveAuthenticationChallenge([delegate respondsToSelector:@selector(dataTask:didReceiveAuthenticationChallenge:completionHandler:)])
+        , m_respondsToWillPerformHTTPRedirection([delegate respondsToSelector:@selector(dataTask:willPerformHTTPRedirection:newRequest:decisionHandler:)])
+        , m_respondsToDidReceiveResponse([delegate respondsToSelector:@selector(dataTask:didReceiveResponse:decisionHandler:)])
+        , m_respondsToDidReceiveData([delegate respondsToSelector:@selector(dataTask:didReceiveData:)])
+        , m_respondsToDidCompleteWithError([delegate respondsToSelector:@selector(dataTask:didCompleteWithError:)]) { }
+
+    void didReceiveChallenge(API::DataTask& task, WebCore::AuthenticationChallenge&& challenge, CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, WebCore::Credential&&)>&& completionHandler) const final
+    {
+        if (!m_delegate || !m_respondsToDidReceiveAuthenticationChallenge)
+            return completionHandler(WebKit::AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue, { });
+        auto checker = WebKit::CompletionHandlerCallChecker::create(m_delegate.get().get(), @selector(dataTask:didReceiveAuthenticationChallenge:completionHandler:));
+        [m_delegate dataTask:wrapper(task) didReceiveAuthenticationChallenge:mac(challenge) completionHandler:makeBlockPtr([checker = WTFMove(checker), completionHandler = WTFMove(completionHandler)](NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential) mutable {
+            if (checker->completionHandlerHasBeenCalled())
+                return;
+            checker->didCallCompletionHandler();
+            completionHandler(WebKit::toAuthenticationChallengeDisposition(disposition), WebCore::Credential(credential));
+        }).get()];
+    }
+
+    void willPerformHTTPRedirection(API::DataTask& task, WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request, CompletionHandler<void(bool)>&& completionHandler) const final
+    {
+        if (!m_delegate || !m_respondsToWillPerformHTTPRedirection)
+            return completionHandler(true);
+        auto checker = WebKit::CompletionHandlerCallChecker::create(m_delegate.get().get(), @selector(dataTask:willPerformHTTPRedirection:newRequest:decisionHandler:));
+        [m_delegate dataTask:wrapper(task) willPerformHTTPRedirection:(NSHTTPURLResponse *)response.nsURLResponse() newRequest:request.nsURLRequest(WebCore::HTTPBodyUpdatePolicy::UpdateHTTPBody) decisionHandler:makeBlockPtr([checker = WTFMove(checker), completionHandler = WTFMove(completionHandler)] (_WKDataTaskRedirectPolicy policy) mutable {
+            if (checker->completionHandlerHasBeenCalled())
+                return;
+            checker->didCallCompletionHandler();
+            completionHandler(policy == _WKDataTaskRedirectPolicyAllow);
+        }).get()];
+    }
+
+    void didReceiveResponse(API::DataTask& task, WebCore::ResourceResponse&& response, CompletionHandler<void(bool)>&& completionHandler) const final
+    {
+        if (!m_delegate || !m_respondsToDidReceiveResponse)
+            return completionHandler(true);
+        auto checker = WebKit::CompletionHandlerCallChecker::create(m_delegate.get().get(), @selector(dataTask:didReceiveResponse:decisionHandler:));
+        [m_delegate dataTask:wrapper(task) didReceiveResponse:response.nsURLResponse() decisionHandler:makeBlockPtr([checker = WTFMove(checker), completionHandler = WTFMove(completionHandler)] (_WKDataTaskResponsePolicy policy) mutable {
+            if (checker->completionHandlerHasBeenCalled())
+                return;
+            checker->didCallCompletionHandler();
+            completionHandler(policy == _WKDataTaskResponsePolicyAllow);
+        }).get()];
+    }
+
+    void didReceiveData(API::DataTask& task, const IPC::DataReference& data) const final
+    {
+        if (!m_delegate || !m_respondsToDidReceiveData)
+            return;
+        [m_delegate dataTask:wrapper(task) didReceiveData:adoptNS([[NSData alloc] initWithBytes:data.data() length:data.size()]).get()];
+    }
+
+    void didCompleteWithError(API::DataTask& task, WebCore::ResourceError&& error) const final
+    {
+        if (!m_delegate || !m_respondsToDidCompleteWithError)
+            return;
+        [m_delegate dataTask:wrapper(task) didCompleteWithError:error.nsError()];
+        wrapper(task)->_delegate = nil;
+    }
+
+    WeakObjCPtr<id <_WKDataTaskDelegate> > m_delegate;
+
+    bool m_respondsToDidReceiveAuthenticationChallenge : 1;
+    bool m_respondsToWillPerformHTTPRedirection : 1;
+    bool m_respondsToDidReceiveResponse : 1;
+    bool m_respondsToDidReceiveData : 1;
+    bool m_respondsToDidCompleteWithError : 1;
+};
+
+@implementation _WKDataTask
+
+- (void)cancel
+{
+    _dataTask->cancel();
+    _delegate = nil;
+}
+
+- (WKWebView *)webView
+{
+    auto* page = _dataTask->page();
+    if (!page)
+        return nil;
+    return page->cocoaView().get();
+}
+
+- (id <_WKDataTaskDelegate>)delegate
+{
+    return _delegate.get();
+}
+
+- (void)setDelegate:(id <_WKDataTaskDelegate>)delegate
+{
+    _delegate = delegate;
+    _dataTask->setClient(WKDataTaskClient::create(delegate));
+}
+
+- (void)dealloc
+{
+    if (WebCoreObjCScheduleDeallocateOnMainRunLoop(_WKDataTask.class, self))
+        return;
+    _dataTask->~DataTask();
+    [super dealloc];
+}
+
+#pragma mark WKObject protocol implementation
+
+- (API::Object&)_apiObject
+{
+    return *_dataTask;
+}
+
+@end

Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskDelegate.h (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskDelegate.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskDelegate.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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 <Foundation/Foundation.h>
+#import <WebKit/WKFoundation.h>
+
+@class _WKDataTask;
+
+typedef NS_ENUM(NSInteger, _WKDataTaskRedirectPolicy) {
+    _WKDataTaskRedirectPolicyCancel,
+    _WKDataTaskRedirectPolicyAllow,
+} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
+typedef NS_ENUM(NSInteger, _WKDataTaskResponsePolicy) {
+    _WKDataTaskResponsePolicyCancel,
+    _WKDataTaskResponsePolicyAllow,
+} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol _WKDataTaskDelegate <NSObject>
+
+@optional
+
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler;
+- (void)dataTask:(_WKDataTask *)dataTask willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request decisionHandler:(void (^)(_WKDataTaskRedirectPolicy))decisionHandler;
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response decisionHandler:(void (^)(_WKDataTaskResponsePolicy))decisionHandler;
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveData:(NSData *)data;
+- (void)dataTask:(_WKDataTask *)dataTask didCompleteWithError:(nullable NSError *)error;
+
+@end
+
+NS_ASSUME_NONNULL_END

Copied: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskInternal.h (from rev 290721, trunk/Source/WebKit/Shared/Authentication/cocoa/AuthenticationChallengeDispositionCocoa.h) (0 => 290722)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskInternal.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKDataTaskInternal.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 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 "APIDataTask.h"
+#import "WKObject.h"
+#import "_WKDataTask.h"
+#import <wtf/WeakObjCPtr.h>
+
+namespace WebKit {
+
+template<> struct WrapperTraits<API::DataTask> {
+    using WrapperClass = _WKDataTask;
+};
+
+}
+
+@interface _WKDataTask () <WKObject> {
+@package
+    API::ObjectStorage<API::DataTask> _dataTask;
+    RetainPtr<id <_WKDataTaskDelegate> > _delegate;
+}
+@end

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2022-03-02 08:09:08 UTC (rev 290722)
@@ -28,6 +28,8 @@
 
 #include "APIContentRuleList.h"
 #include "APICustomProtocolManagerClient.h"
+#include "APIDataTask.h"
+#include "APIDataTaskClient.h"
 #include "APINavigation.h"
 #include "AuthenticationChallengeProxy.h"
 #include "AuthenticationManager.h"
@@ -61,6 +63,7 @@
 #include "WebsiteDataStoreParameters.h"
 #include <WebCore/ClientOrigin.h>
 #include <WebCore/RegistrableDomain.h>
+#include <WebCore/ResourceError.h>
 #include <wtf/CallbackAggregator.h>
 #include <wtf/CompletionHandler.h>
 
@@ -337,14 +340,61 @@
     return m_downloadProxyMap->createDownloadProxy(dataStore, processPool, resourceRequest, frameInfo, originatingPage);
 }
 
-void NetworkProcessProxy::requestResource(WebPageProxyIdentifier pageID, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
+void NetworkProcessProxy::dataTaskWithRequest(WebPageProxy& page, PAL::SessionID sessionID, WebCore::ResourceRequest&& request, CompletionHandler<void(API::DataTask&)>&& completionHandler)
 {
-    sendWithAsyncReply(Messages::NetworkProcess::RequestResource(pageID, sessionID, request, IPC::FormDataReference(request.httpBody())), [completionHandler = WTFMove(completionHandler)] (IPC::DataReference&& data, WebCore::ResourceResponse&& response, WebCore::ResourceError&& error) mutable {
-        auto buffer = SharedBuffer::create(data.data(), data.size());
-        completionHandler(WTFMove(buffer), WTFMove(response), WTFMove(error));
+    sendWithAsyncReply(Messages::NetworkProcess::DataTaskWithRequest(page.identifier(), sessionID, request, IPC::FormDataReference(request.httpBody())), [this, protectedThis = Ref { *this }, weakPage = WeakPtr { page }, completionHandler = WTFMove(completionHandler), originalURL = request.url()] (DataTaskIdentifier identifier) mutable {
+        MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+        auto dataTask = API::DataTask::create(identifier, WTFMove(weakPage), WTFMove(originalURL));
+        completionHandler(dataTask);
+        m_dataTasks.add(identifier, WTFMove(dataTask));
     });
 }
 
+void NetworkProcessProxy::dataTaskReceivedChallenge(DataTaskIdentifier identifier, WebCore::AuthenticationChallenge&& challenge, CompletionHandler<void(AuthenticationChallengeDisposition, WebCore::Credential&&)>&& completionHandler)
+{
+    MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+    if (auto task = m_dataTasks.get(identifier))
+        task->client().didReceiveChallenge(*task, WTFMove(challenge), WTFMove(completionHandler));
+    else
+        completionHandler(AuthenticationChallengeDisposition::RejectProtectionSpaceAndContinue, { });
+}
+
+void NetworkProcessProxy::dataTaskWillPerformHTTPRedirection(DataTaskIdentifier identifier, WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request, CompletionHandler<void(bool)>&& completionHandler)
+{
+    MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+    if (auto task = m_dataTasks.get(identifier))
+        task->client().willPerformHTTPRedirection(*task, WTFMove(response), WTFMove(request), WTFMove(completionHandler));
+}
+
+void NetworkProcessProxy::dataTaskDidReceiveResponse(DataTaskIdentifier identifier, WebCore::ResourceResponse&& response, CompletionHandler<void(bool)>&& completionHandler)
+{
+    MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+    if (auto task = m_dataTasks.get(identifier))
+        task->client().didReceiveResponse(*task, WTFMove(response), WTFMove(completionHandler));
+    else
+        completionHandler(false);
+}
+
+void NetworkProcessProxy::dataTaskDidReceiveData(DataTaskIdentifier identifier, const IPC::DataReference& data)
+{
+    MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+    if (auto task = m_dataTasks.get(identifier))
+        task->client().didReceiveData(*task, data);
+}
+
+void NetworkProcessProxy::dataTaskDidCompleteWithError(DataTaskIdentifier identifier, WebCore::ResourceError&& error)
+{
+    MESSAGE_CHECK(decltype(m_dataTasks)::isValidKey(identifier));
+    if (auto task = m_dataTasks.take(identifier))
+        task->client().didCompleteWithError(*task, WTFMove(error));
+}
+
+void NetworkProcessProxy::cancelDataTask(DataTaskIdentifier identifier, PAL::SessionID sessionID)
+{
+    m_dataTasks.remove(identifier);
+    send(Messages::NetworkProcess::CancelDataTask(identifier, sessionID), 0);
+}
+
 void NetworkProcessProxy::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void(WebsiteData)>&& completionHandler)
 {
     sendWithAsyncReply(Messages::NetworkProcess::FetchWebsiteData(sessionID, dataTypes, fetchOptions), WTFMove(completionHandler));
@@ -384,6 +434,9 @@
         processPool->networkProcessDidTerminate(*this, reason);
     for (auto& websiteDataStore : copyToVectorOf<Ref<WebsiteDataStore>>(m_websiteDataStores))
         websiteDataStore->networkProcessDidTerminate(*this);
+    for (auto& task : m_dataTasks.values())
+        task->client().didCompleteWithError(task, WebCore::internalError(task->originalURL()));
+    m_dataTasks.clear();
 }
 
 void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -27,6 +27,8 @@
 
 #include "AppPrivacyReport.h"
 #include "AuxiliaryProcessProxy.h"
+#include "DataReference.h"
+#include "DataTaskIdentifier.h"
 #include "IdentifierTypes.h"
 #include "NetworkProcessProxyMessagesReplies.h"
 #include "NetworkResourceLoadIdentifier.h"
@@ -58,6 +60,7 @@
 
 namespace API {
 class CustomProtocolManagerClient;
+class DataTask;
 }
 
 namespace PAL {
@@ -126,7 +129,7 @@
     void getNetworkProcessConnection(WebProcessProxy&, Messages::WebProcessProxy::GetNetworkProcessConnectionDelayedReply&&);
 
     DownloadProxy& createDownloadProxy(WebsiteDataStore&, WebProcessPool&, const WebCore::ResourceRequest&, const FrameInfoData&, WebPageProxy* originatingPage);
-    void requestResource(WebPageProxyIdentifier, PAL::SessionID, WebCore::ResourceRequest&&, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&);
+    void dataTaskWithRequest(WebPageProxy&, PAL::SessionID, WebCore::ResourceRequest&&, CompletionHandler<void(API::DataTask&)>&&);
 
     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, CompletionHandler<void(WebsiteData)>&&);
     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, CompletionHandler<void()>&& completionHandler);
@@ -289,6 +292,13 @@
     void deletePushAndNotificationRegistration(PAL::SessionID, const WebCore::SecurityOriginData&, CompletionHandler<void(const String&)>&&);
     void getOriginsWithPushAndNotificationPermissions(PAL::SessionID, CompletionHandler<void(const Vector<WebCore::SecurityOriginData>&)>&&);
 
+    void dataTaskReceivedChallenge(DataTaskIdentifier, WebCore::AuthenticationChallenge&&, CompletionHandler<void(AuthenticationChallengeDisposition, WebCore::Credential&&)>&&);
+    void dataTaskWillPerformHTTPRedirection(DataTaskIdentifier, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, CompletionHandler<void(bool)>&&);
+    void dataTaskDidReceiveResponse(DataTaskIdentifier, WebCore::ResourceResponse&&, CompletionHandler<void(bool)>&&);
+    void dataTaskDidReceiveData(DataTaskIdentifier, const IPC::DataReference&);
+    void dataTaskDidCompleteWithError(DataTaskIdentifier, WebCore::ResourceError&&);
+    void cancelDataTask(DataTaskIdentifier, PAL::SessionID);
+
 private:
     explicit NetworkProcessProxy();
 
@@ -398,6 +408,7 @@
 
     WeakHashSet<WebsiteDataStore> m_websiteDataStores;
     UniqueRef<WebCookieManagerProxy> m_cookieManager;
+    HashMap<DataTaskIdentifier, Ref<API::DataTask>> m_dataTasks;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2022-03-02 08:09:08 UTC (rev 290722)
@@ -89,4 +89,12 @@
 #if ENABLE(APPLE_PAY_REMOTE_UI_USES_SCENE)
     GetWindowSceneIdentifierForPaymentPresentation(WebKit::WebPageProxyIdentifier webPageProxyIdentifier) -> (String sceneID) Async
 #endif
+
+    DataTaskReceivedChallenge(WebKit::DataTaskIdentifier identifier, WebCore::AuthenticationChallenge challenge) -> (enum:uint8_t WebKit::AuthenticationChallengeDisposition disposition, WebCore::Credential credential) Async
+    DataTaskWillPerformHTTPRedirection(WebKit::DataTaskIdentifier identifier, WebCore::ResourceResponse response, WebCore::ResourceRequest request) -> (bool allowed) Async
+    DataTaskDidReceiveResponse(WebKit::DataTaskIdentifier identifier, WebCore::ResourceResponse response) -> (bool allowed) Async
+    DataTaskDidReceiveData(WebKit::DataTaskIdentifier identifier, IPC::DataReference data)
+    DataTaskDidCompleteWithError(WebKit::DataTaskIdentifier identifier, WebCore::ResourceError error)
 }
+
+}

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-03-02 08:09:08 UTC (rev 290722)
@@ -6470,9 +6470,9 @@
     download.setDidStartCallback(WTFMove(completionHandler));
 }
 
-void WebPageProxy::requestResource(WebCore::ResourceRequest&& request, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&& completionHandler)
+void WebPageProxy::dataTaskWithRequest(WebCore::ResourceRequest&& request, CompletionHandler<void(API::DataTask&)>&& completionHandler)
 {
-    websiteDataStore().networkProcess().requestResource(identifier(), sessionID(), WTFMove(request), WTFMove(completionHandler));
+    websiteDataStore().networkProcess().dataTaskWithRequest(*this, sessionID(), WTFMove(request), WTFMove(completionHandler));
 }
 
 void WebPageProxy::didChangeContentSize(const IntSize& size)

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -201,6 +201,7 @@
 class Attachment;
 class ContentWorld;
 class ContextMenuClient;
+class DataTask;
 class DestinationColorSpace;
 class Error;
 class FindClient;
@@ -1387,7 +1388,7 @@
     void handleDownloadRequest(DownloadProxy&);
     void resumeDownload(const API::Data& resumeData, const String& path, CompletionHandler<void(DownloadProxy*)>&&);
     void downloadRequest(WebCore::ResourceRequest&&, CompletionHandler<void(DownloadProxy*)>&&);
-    void requestResource(WebCore::ResourceRequest&&, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&, WebCore::ResourceResponse&&, WebCore::ResourceError&&)>&&);
+    void dataTaskWithRequest(WebCore::ResourceRequest&&, CompletionHandler<void(API::DataTask&)>&&);
 
     void advanceToNextMisspelling(bool startBeforeSelection);
     void changeSpellingToWord(const String& word);

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -27,6 +27,16 @@
 
 #import "NativeWebMouseEvent.h"
 
+namespace WebCore {
+class FloatRect;
+}
+
+namespace WebKit {
+struct InteractionInformationAtPosition;
+struct InteractionInformationRequest;
+}
+
+@class UIView;
 @class WKHoverPlatter;
 
 @protocol WKHoverPlatterDelegate

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm (290721 => 290722)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -29,9 +29,11 @@
 #if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
 
 #import "WKHoverPlatterParameters.h"
+#import <UIKit/UIKit.h>
 #import <WebCore/PathUtilities.h>
 #import <WebCore/WebCoreCALayerExtras.h>
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
+#import <wtf/BlockPtr.h>
 
 static RetainPtr<CABasicAnimation> createBaseAnimation()
 {

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (290721 => 290722)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2022-03-02 08:09:08 UTC (rev 290722)
@@ -1228,6 +1228,8 @@
 		5C20F679276A6DB6006CAC22 /* ArgumentCoders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D610413A7F03A00F95D4E /* ArgumentCoders.cpp */; };
 		5C26958520043212005C439B /* WKOpenPanelParametersPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C26958420042F12005C439B /* WKOpenPanelParametersPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5C298DA01C3DF02100470AFE /* PendingDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C298D9E1C3DEF2900470AFE /* PendingDownload.h */; };
+		5C2C6FA927C9E5E200CCDA9E /* _WKDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2C6FA427C9529900CCDA9E /* _WKDataTask.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		5C2C6FAA27C9E5EB00CCDA9E /* _WKDataTaskDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2C6FA327C9529900CCDA9E /* _WKDataTaskDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5C2D5748257FFA4B00679A72 /* WKContextDownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2D5747257FFA1200679A72 /* WKContextDownloadClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5C2EBDFA2564380B00D55B05 /* WKDownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2EBDF92564352000D55B05 /* WKDownloadClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5C359C0D2154739F009E7948 /* WKDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C359C0C21547321009E7948 /* WKDeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4921,6 +4923,16 @@
 		5C2B1AF3223AB72800B91CF7 /* DownloadMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DownloadMonitor.cpp; sourceTree = "<group>"; };
 		5C2B1AF4223AB72800B91CF7 /* DownloadMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadMonitor.h; sourceTree = "<group>"; };
 		5C2B1AF5223C1FD200B91CF7 /* DownloadProxyMapCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DownloadProxyMapCocoa.mm; sourceTree = "<group>"; };
+		5C2C6F9E27C9523500CCDA9E /* APIDataTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIDataTask.h; sourceTree = "<group>"; };
+		5C2C6F9F27C9523500CCDA9E /* APIDataTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIDataTask.cpp; sourceTree = "<group>"; };
+		5C2C6FA027C9523500CCDA9E /* APIDataTaskClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIDataTaskClient.h; sourceTree = "<group>"; };
+		5C2C6FA227C9529900CCDA9E /* _WKDataTask.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKDataTask.mm; sourceTree = "<group>"; };
+		5C2C6FA327C9529900CCDA9E /* _WKDataTaskDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDataTaskDelegate.h; sourceTree = "<group>"; };
+		5C2C6FA427C9529900CCDA9E /* _WKDataTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDataTask.h; sourceTree = "<group>"; };
+		5C2C6FA527C9529900CCDA9E /* _WKDataTaskInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDataTaskInternal.h; sourceTree = "<group>"; };
+		5C2C6FA627C958FC00CCDA9E /* DataTaskIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTaskIdentifier.h; sourceTree = "<group>"; };
+		5C2C6FA727C96FF900CCDA9E /* WKURLSessionTaskDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKURLSessionTaskDelegate.mm; sourceTree = "<group>"; };
+		5C2C6FA827C96FF900CCDA9E /* WKURLSessionTaskDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKURLSessionTaskDelegate.h; sourceTree = "<group>"; };
 		5C2D5747257FFA1200679A72 /* WKContextDownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContextDownloadClient.h; sourceTree = "<group>"; };
 		5C2EBDF92564352000D55B05 /* WKDownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadClient.h; sourceTree = "<group>"; };
 		5C359C0C21547321009E7948 /* WKDeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDeprecated.h; sourceTree = "<group>"; };
@@ -7305,6 +7317,7 @@
 				5106D7BF18BDBE73000AB166 /* ContextMenuContextData.cpp */,
 				5106D7C018BDBE73000AB166 /* ContextMenuContextData.h */,
 				99F642D21FABE378009621E9 /* CoordinateSystem.h */,
+				5C2C6FA627C958FC00CCDA9E /* DataTaskIdentifier.h */,
 				99036AE823A970870000B06A /* DebuggableInfoData.cpp */,
 				99036AE723A970870000B06A /* DebuggableInfoData.h */,
 				0F189CAB24749F2F00E58D81 /* DisplayLinkObserverID.h */,
@@ -8880,6 +8893,10 @@
 				5C5D2389227A1892000B9BDA /* _WKCustomHeaderFields.h */,
 				5C5D2388227A1892000B9BDA /* _WKCustomHeaderFields.mm */,
 				5C5D2387227A1891000B9BDA /* _WKCustomHeaderFieldsInternal.h */,
+				5C2C6FA427C9529900CCDA9E /* _WKDataTask.h */,
+				5C2C6FA227C9529900CCDA9E /* _WKDataTask.mm */,
+				5C2C6FA327C9529900CCDA9E /* _WKDataTaskDelegate.h */,
+				5C2C6FA527C9529900CCDA9E /* _WKDataTaskInternal.h */,
 				83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */,
 				A1A4FE5718DCE9FA00B5EA8A /* _WKDownload.h */,
 				A1A4FE5818DCE9FA00B5EA8A /* _WKDownload.mm */,
@@ -10485,6 +10502,8 @@
 				5C20CB9B1BB0DCD200895BB1 /* NetworkSessionCocoa.mm */,
 				41287D4C225C05C5009A3E26 /* WebSocketTaskCocoa.h */,
 				41287D4B225C05C4009A3E26 /* WebSocketTaskCocoa.mm */,
+				5C2C6FA827C96FF900CCDA9E /* WKURLSessionTaskDelegate.h */,
+				5C2C6FA727C96FF900CCDA9E /* WKURLSessionTaskDelegate.mm */,
 			);
 			path = cocoa;
 			sourceTree = "<group>";
@@ -11327,6 +11346,9 @@
 				5CE0C367229F2D3E003695F0 /* APIContextMenuElementInfo.h */,
 				5C5D238A227A1D9B000B9BDA /* APICustomHeaderFields.h */,
 				7A821F4F1E2F7A5C00604577 /* APICustomProtocolManagerClient.h */,
+				5C2C6F9F27C9523500CCDA9E /* APIDataTask.cpp */,
+				5C2C6F9E27C9523500CCDA9E /* APIDataTask.h */,
+				5C2C6FA027C9523500CCDA9E /* APIDataTaskClient.h */,
 				99036AE423A958740000B06A /* APIDebuggableInfo.cpp */,
 				99036AE323A958740000B06A /* APIDebuggableInfo.h */,
 				83891B621A68B3420030F386 /* APIDiagnosticLoggingClient.h */,
@@ -12928,6 +12950,8 @@
 				5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */,
 				1A5704F81BE01FF400874AF1 /* _WKContextMenuElementInfo.h in Headers */,
 				5C5D238C227A2CDA000B9BDA /* _WKCustomHeaderFields.h in Headers */,
+				5C2C6FA927C9E5E200CCDA9E /* _WKDataTask.h in Headers */,
+				5C2C6FAA27C9E5EB00CCDA9E /* _WKDataTaskDelegate.h in Headers */,
 				83891B691A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h in Headers */,
 				A1A4FE5A18DCE9FA00B5EA8A /* _WKDownload.h in Headers */,
 				A1A4FE6118DD54A400B5EA8A /* _WKDownloadDelegate.h in Headers */,

Modified: trunk/Tools/ChangeLog (290721 => 290722)


--- trunk/Tools/ChangeLog	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Tools/ChangeLog	2022-03-02 08:09:08 UTC (rev 290722)
@@ -1,3 +1,17 @@
+2022-03-02  Alex Christensen  <[email protected]>
+
+        Add SPI _WKDataTask
+        https://bugs.webkit.org/show_bug.cgi?id=237234
+
+        Reviewed by Tim Horton.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm:
+        (-[TestDataTaskDelegate dataTask:didReceiveAuthenticationChallenge:completionHandler:]):
+        (-[TestDataTaskDelegate dataTask:didReceiveResponse:decisionHandler:]):
+        (-[TestDataTaskDelegate dataTask:didReceiveData:]):
+        (-[TestDataTaskDelegate dataTask:didCompleteWithError:]):
+        (TEST):
+
 2022-03-01  Wenson Hsieh  <[email protected]>
 
         Clipboard Paste dialog doesn't show on external monitors

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm (290721 => 290722)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/NetworkProcess.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -33,6 +33,8 @@
 #import <WebKit/WKScriptMessageHandler.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/_WKDataTask.h>
+#import <WebKit/_WKDataTaskDelegate.h>
 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
@@ -352,8 +354,60 @@
     EXPECT_EQ(webPID2, [webView2 _webProcessIdentifier]);
 }
 
-TEST(NetworkProcess, LoadResource)
+#if HAVE(NSURLSESSION_TASK_DELEGATE)
+
+@interface TestDataTaskDelegate : NSObject<_WKDataTaskDelegate>
+
+@property (nonatomic, copy) void(^didReceiveAuthenticationChallenge)(_WKDataTask *, NSURLAuthenticationChallenge *, void(^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *));
+@property (nonatomic, copy) void(^willPerformHTTPRedirection)(_WKDataTask *, NSHTTPURLResponse *, NSURLRequest *, void(^)(_WKDataTaskRedirectPolicy));
+@property (nonatomic, copy) void (^didReceiveResponse)(_WKDataTask *, NSURLResponse *, void (^)(_WKDataTaskResponsePolicy));
+@property (nonatomic, copy) void (^didReceiveData)(_WKDataTask *, NSData *);
+@property (nonatomic, copy) void (^didCompleteWithError)(_WKDataTask *, NSError *);
+
+@end
+
+@implementation TestDataTaskDelegate
+
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
 {
+    if (_didReceiveAuthenticationChallenge)
+        _didReceiveAuthenticationChallenge(dataTask, challenge, completionHandler);
+    else
+        completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
+}
+
+- (void)dataTask:(_WKDataTask *)dataTask willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request decisionHandler:(void (^)(_WKDataTaskRedirectPolicy))decisionHandler
+{
+    if (_willPerformHTTPRedirection)
+        _willPerformHTTPRedirection(dataTask, response, request, decisionHandler);
+    else
+        decisionHandler(_WKDataTaskRedirectPolicyAllow);
+}
+
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response decisionHandler:(void (^)(_WKDataTaskResponsePolicy))decisionHandler
+{
+    if (_didReceiveResponse)
+        _didReceiveResponse(dataTask, response, decisionHandler);
+    else
+        decisionHandler(_WKDataTaskResponsePolicyAllow);
+}
+
+- (void)dataTask:(_WKDataTask *)dataTask didReceiveData:(NSData *)data
+{
+    if (_didReceiveData)
+        _didReceiveData(dataTask, data);
+}
+
+- (void)dataTask:(_WKDataTask *)dataTask didCompleteWithError:(NSError *)error
+{
+    if (_didCompleteWithError)
+        _didCompleteWithError(dataTask, error);
+}
+
+@end
+
+TEST(_WKDataTask, Basic)
+{
     using namespace TestWebKitAPI;
     auto html = "<script>document.cookie='testkey=value'</script>";
     auto secondResponse = "second response";
@@ -377,12 +431,27 @@
     [postRequest setHTTPMethod:@"POST"];
     auto requestBody = "request body";
     [postRequest setHTTPBody:[NSData dataWithBytes:requestBody length:strlen(requestBody)]];
-    [webView _requestResource:postRequest.get() completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
-        EXPECT_NULL(error);
-        EXPECT_WK_STREQ(response.URL.absoluteString, postRequest.get().URL.absoluteString);
-        EXPECT_EQ(data.length, strlen(secondResponse));
-        EXPECT_TRUE(!memcmp(data.bytes, secondResponse, data.length));
-        done = true;
+    [webView _dataTaskWithRequest:postRequest.get() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        __block bool receivedResponse = false;
+        delegate.get().didReceiveResponse = ^(_WKDataTask *, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            EXPECT_WK_STREQ(response.URL.absoluteString, postRequest.get().URL.absoluteString);
+            receivedResponse = true;
+            decisionHandler(_WKDataTaskResponsePolicyAllow);
+        };
+        __block bool receivedData = false;
+        delegate.get().didReceiveData = ^(_WKDataTask *, NSData *data) {
+            EXPECT_TRUE(receivedResponse);
+            EXPECT_EQ(data.length, strlen(secondResponse));
+            EXPECT_TRUE(!memcmp(data.bytes, secondResponse, data.length));
+            receivedData = true;
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *, NSError *error) {
+            EXPECT_TRUE(receivedData);
+            EXPECT_NULL(error);
+            done = true;
+        };
     }];
     Util::run(&done);
     EXPECT_TRUE(strnstr(secondRequest.data(), "Cookie: testkey=value\r\n", secondRequest.size()));
@@ -389,12 +458,203 @@
     EXPECT_WK_STREQ(HTTPServer::parseBody(secondRequest), requestBody);
 
     done = false;
-    [webView _requestResource:[NSURLRequest requestWithURL:[NSURL URLWithString:@"blob:blank"]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
-        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
-        EXPECT_EQ(error.code, NSURLErrorUnsupportedURL);
-        EXPECT_NULL(data);
-        EXPECT_NULL(response);
-        done = true;
+    __block RetainPtr<_WKDataTask> retainedTask;
+    [webView _dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"blob:blank"]] completionHandler:^(_WKDataTask *task) {
+        retainedTask = task;
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        __block bool receivedResponse = false;
+        delegate.get().didReceiveResponse = ^(_WKDataTask *, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            receivedResponse = true;
+        };
+        __block bool receivedData = false;
+        delegate.get().didReceiveData = ^(_WKDataTask *, NSData *data) {
+            receivedData = true;
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *task, NSError *error) {
+            EXPECT_FALSE(receivedResponse);
+            EXPECT_FALSE(receivedData);
+            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
+            EXPECT_EQ(error.code, NSURLErrorUnsupportedURL);
+            EXPECT_NOT_NULL(task.delegate);
+            done = true;
+        };
     }];
     Util::run(&done);
+    EXPECT_NOT_NULL(retainedTask.get());
+    EXPECT_NULL(retainedTask.get().delegate);
 }
+
+TEST(_WKDataTask, Challenge)
+{
+    using namespace TestWebKitAPI;
+    HTTPServer server(HTTPServer::respondWithChallengeThenOK, HTTPServer::Protocol::Https);
+    auto webView = adoptNS([TestWKWebView new]);
+
+    __block bool done = false;
+    [webView _dataTaskWithRequest:server.request() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        __block bool receivedServerTrustChallenge = false;
+        __block bool receivedBasicAuthChallenge = false;
+        delegate.get().didReceiveAuthenticationChallenge = ^(_WKDataTask *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+            if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
+                EXPECT_FALSE(receivedBasicAuthChallenge);
+                EXPECT_FALSE(receivedServerTrustChallenge);
+                receivedServerTrustChallenge = true;
+                completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+                return;
+            }
+            EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodHTTPBasic);
+            EXPECT_FALSE(receivedBasicAuthChallenge);
+            EXPECT_TRUE(receivedServerTrustChallenge);
+            receivedBasicAuthChallenge = true;
+            completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
+        };
+        __block bool receivedData = false;
+        delegate.get().didReceiveData = ^(_WKDataTask *, NSData *data) {
+            const char* expectedResponse = "<script>alert('success!')</script>";
+            EXPECT_EQ(data.length, strlen(expectedResponse));
+            EXPECT_TRUE(!memcmp(data.bytes, expectedResponse, data.length));
+            receivedData = true;
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *, NSError *error) {
+            EXPECT_TRUE(receivedData);
+            EXPECT_TRUE(receivedBasicAuthChallenge);
+            EXPECT_TRUE(receivedServerTrustChallenge);
+            EXPECT_NULL(error);
+            done = true;
+        };
+    }];
+    Util::run(&done);
+}
+
+void sendLoop(TestWebKitAPI::Connection connection, bool& sentWithError)
+{
+    Vector<uint8_t> bytes(1000, 0);
+    connection.sendAndReportError(WTFMove(bytes), [&, connection] (bool sawError) {
+        if (sawError)
+            sentWithError = true;
+        else
+            sendLoop(connection, sentWithError);
+    });
+}
+
+TEST(_WKDataTask, Cancel)
+{
+    using namespace TestWebKitAPI;
+    bool sentWithError { false };
+    HTTPServer server([&] (Connection connection) {
+        connection.receiveHTTPRequest([&, connection] (Vector<char>&&) {
+            auto* header = "HTTP/1.1 200 OK\r\n\r\n";
+            connection.send(header, [&, connection] {
+                sendLoop(connection, sentWithError);
+            });
+        });
+    });
+
+    auto webView = adoptNS([WKWebView new]);
+    [webView _dataTaskWithRequest:server.request() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        delegate.get().didReceiveResponse = ^(_WKDataTask *task, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            decisionHandler(_WKDataTaskResponsePolicyAllow);
+            dispatch_async(dispatch_get_main_queue(), ^{
+                EXPECT_NOT_NULL(task.delegate);
+                [task cancel];
+                EXPECT_NULL(task.delegate);
+            });
+        };
+    }];
+    Util::run(&sentWithError);
+
+    __block bool completed { false };
+    [webView _dataTaskWithRequest:server.request() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        delegate.get().didReceiveResponse = ^(_WKDataTask *task, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            decisionHandler(_WKDataTaskResponsePolicyCancel);
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *, NSError *error) {
+            EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
+            EXPECT_EQ(error.code, NSURLErrorCancelled);
+            completed = true;
+        };
+    }];
+    Util::run(&completed);
+}
+
+TEST(_WKDataTask, Redirect)
+{
+    using namespace TestWebKitAPI;
+    HTTPServer server { {
+        { "/", { 301, { { "Location", "/redirectTarget" }, { "Custom-Name", "Custom-Value" } } } },
+        { "/redirectTarget", { "hi" } },
+    } };
+    auto webView = adoptNS([WKWebView new]);
+    RetainPtr<NSURLRequest> serverRequest = server.request();
+    __block bool receivedData { false };
+    [webView _dataTaskWithRequest:serverRequest.get() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        delegate.get().willPerformHTTPRedirection = ^(_WKDataTask *task, NSHTTPURLResponse *response, NSURLRequest *request, void(^decisionHandler)(_WKDataTaskRedirectPolicy)) {
+            EXPECT_WK_STREQ(serverRequest.get().URL.absoluteString, response.URL.absoluteString);
+            EXPECT_WK_STREQ([serverRequest.get().URL.absoluteString stringByAppendingString:@"redirectTarget"], request.URL.absoluteString);
+            EXPECT_WK_STREQ([response valueForHTTPHeaderField:@"Custom-Name"], "Custom-Value");
+            decisionHandler(_WKDataTaskRedirectPolicyAllow);
+        };
+        delegate.get().didReceiveData = ^(_WKDataTask *, NSData *data) {
+            EXPECT_EQ(data.length, strlen("hi"));
+            EXPECT_TRUE(!memcmp(data.bytes, "hi", data.length));
+            receivedData = true;
+        };
+    }];
+    Util::run(&receivedData);
+    
+    __block bool completed { false };
+    __block bool receivedResponse { false };
+    [webView _dataTaskWithRequest:serverRequest.get() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        delegate.get().willPerformHTTPRedirection = ^(_WKDataTask *task, NSHTTPURLResponse *response, NSURLRequest *request, void(^decisionHandler)(_WKDataTaskRedirectPolicy)) {
+            decisionHandler(_WKDataTaskRedirectPolicyCancel);
+        };
+        delegate.get().didReceiveResponse = ^(_WKDataTask *task, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            EXPECT_WK_STREQ(response.URL.absoluteString, serverRequest.get().URL.absoluteString);
+            EXPECT_EQ(((NSHTTPURLResponse *)response).statusCode, 301);
+            receivedResponse = true;
+            decisionHandler(_WKDataTaskResponsePolicyAllow);
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *, NSError *error) {
+            EXPECT_TRUE(receivedResponse);
+            EXPECT_NULL(error);
+            completed = true;
+        };
+    }];
+    Util::run(&completed);
+}
+
+TEST(_WKDataTask, Crash)
+{
+    using namespace TestWebKitAPI;
+    HTTPServer server(HTTPServer::respondWithOK);
+    auto webView = adoptNS([WKWebView new]);
+
+    __block bool done = false;
+    [webView _dataTaskWithRequest:server.request() completionHandler:^(_WKDataTask *task) {
+        auto delegate = adoptNS([TestDataTaskDelegate new]);
+        task.delegate = delegate.get();
+        delegate.get().didReceiveResponse = ^(_WKDataTask *task, NSURLResponse *response, void (^decisionHandler)(_WKDataTaskResponsePolicy)) {
+            kill(webView.get().configuration.websiteDataStore._networkProcessIdentifier, SIGKILL);
+            decisionHandler(_WKDataTaskResponsePolicyAllow);
+        };
+        delegate.get().didCompleteWithError = ^(_WKDataTask *, NSError *error) {
+            EXPECT_WK_STREQ(error.domain, WebKitErrorDomain);
+            EXPECT_EQ(error.code, 300);
+            done = true;
+        };
+    }];
+    Util::run(&done);
+}
+
+#endif // HAVE(NSURLSESSION_TASK_DELEGATE)

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h (290721 => 290722)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h	2022-03-02 08:09:08 UTC (rev 290722)
@@ -78,7 +78,7 @@
 public:
     void send(String&&, CompletionHandler<void()>&& = nullptr) const;
     void send(Vector<uint8_t>&&, CompletionHandler<void()>&& = nullptr) const;
-    void send(RetainPtr<dispatch_data_t>&&, CompletionHandler<void()>&& = nullptr) const;
+    void sendAndReportError(Vector<uint8_t>&&, CompletionHandler<void(bool)>&&) const;
     void receiveBytes(CompletionHandler<void(Vector<uint8_t>&&)>&&, size_t minimumSize = 1) const;
     void receiveHTTPRequest(CompletionHandler<void(Vector<char>&&)>&&, Vector<char>&& buffer = { }) const;
     void webSocketHandshake(CompletionHandler<void()>&& = { });
@@ -90,6 +90,8 @@
     Connection(nw_connection_t connection)
         : m_connection(connection) { }
 
+    void send(RetainPtr<dispatch_data_t>&&, CompletionHandler<void(bool)>&&) const;
+
     RetainPtr<nw_connection_t> m_connection;
 };
 

Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (290721 => 290722)


--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2022-03-02 07:08:11 UTC (rev 290721)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm	2022-03-02 08:09:08 UTC (rev 290722)
@@ -414,19 +414,30 @@
 
 void Connection::send(String&& message, CompletionHandler<void()>&& completionHandler) const
 {
-    send(dataFromString(WTFMove(message)), WTFMove(completionHandler));
+    send(dataFromString(WTFMove(message)), [completionHandler = WTFMove(completionHandler)] (bool) mutable {
+        if (completionHandler)
+            completionHandler();
+    });
 }
 
 void Connection::send(Vector<uint8_t>&& message, CompletionHandler<void()>&& completionHandler) const
 {
+    send(dataFromVector(WTFMove(message)), [completionHandler = WTFMove(completionHandler)] (bool) mutable {
+        if (completionHandler)
+            completionHandler();
+    });
+}
+
+void Connection::sendAndReportError(Vector<uint8_t>&& message, CompletionHandler<void(bool)>&& completionHandler) const
+{
     send(dataFromVector(WTFMove(message)), WTFMove(completionHandler));
 }
 
-void Connection::send(RetainPtr<dispatch_data_t>&& message, CompletionHandler<void()>&& completionHandler) const
+void Connection::send(RetainPtr<dispatch_data_t>&& message, CompletionHandler<void(bool)>&& completionHandler) const
 {
     nw_connection_send(m_connection.get(), message.get(), NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, makeBlockPtr([completionHandler = WTFMove(completionHandler)](nw_error_t error) mutable {
         if (completionHandler)
-            completionHandler();
+            completionHandler(!!error);
     }).get());
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to