Expand _WKResourceLoadDelegate callbacks
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jan 2020 18:06:08 +0000 (18:06 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Jan 2020 18:06:08 +0000 (18:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=206037
Source/WebKit:

<rdar://problem/57132290>

Reviewed by Youenn Fablet.

Add 5 informative delegate callbacks at these times during the loading process:
1. When a request is sent.
2. When a redirect happens.
3. When a challenge happens.
4. When a response is received.
5. When loading completes or fails.

As mentioned in r254183 these callbacks are only called when a _WKResourceLoadDelegate is given to a WKWebView.
We add a new struct ResourceLoadInfo which will need to be expanded containing currently only the load identifier.
Covered by new API tests which verify the validity of the sent information.

* NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::didReceiveChallenge):
* NetworkProcess/NetworkLoadClient.h:
(WebKit::NetworkLoadClient::didReceiveChallenge):
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::generateResourceLoadID):
(WebKit::NetworkResourceLoader::startNetworkLoad):
(WebKit::NetworkResourceLoader::resourceLoadInfo):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::didFinishLoading):
(WebKit::NetworkResourceLoader::didFailLoading):
(WebKit::NetworkResourceLoader::didReceiveChallenge):
Add a way to send a message informing that a challenge happened with information gathered from the NetworkResourceLoader,
which previously was not informed of challenges because the challenges went directly from the NetworkLoad to the AuthenticationManager.
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):
(WebKit::NetworkResourceLoader::continueWillSendRequest):
(WebKit::m_shouldCaptureExtraNetworkLoadMetrics): Deleted.
* NetworkProcess/NetworkResourceLoader.h:
* Shared/API/APIObject.h:
* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* Shared/ResourceLoadInfo.h: Added.
(WebKit::ResourceLoadInfo::encode const):
(WebKit::ResourceLoadInfo::decode):
* SourcesCocoa.txt:
* UIProcess/API/APIResourceLoadClient.h:
* UIProcess/API/APIResourceLoadInfo.h: Added.
* UIProcess/API/Cocoa/_WKResourceLoadDelegate.h:
* UIProcess/API/Cocoa/_WKResourceLoadInfo.h: Added.
* UIProcess/API/Cocoa/_WKResourceLoadInfo.mm: Added.
(-[_WKResourceLoadInfo dealloc]):
(-[_WKResourceLoadInfo resourceLoadID]):
(-[_WKResourceLoadInfo _apiObject]):
* UIProcess/API/Cocoa/_WKResourceLoadInfoInternal.h: Added.
* UIProcess/Authentication/AuthenticationChallengeProxy.cpp:
(WebKit::AuthenticationChallengeProxy::AuthenticationChallengeProxy):
An AuthenticationChallengeProxy was only used for challenges that needed credentials, so they wrapped a CompletionHandler.
This new type of informative-only challenge will be given a null CompletionHandler, which means no action can be taken.
* UIProcess/Cocoa/ResourceLoadDelegate.h:
* UIProcess/Cocoa/ResourceLoadDelegate.mm:
(WebKit::ResourceLoadDelegate::setDelegate):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::didSendRequest const):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::didPerformHTTPRedirection const):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::didReceiveChallenge const):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::didReceiveResponse const):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::didCompleteWithError const):
(WebKit::ResourceLoadDelegate::ResourceLoadClient::willSendRequest const): Deleted.
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::resourceLoadDidSendRequest):
(WebKit::NetworkProcessProxy::resourceLoadDidPerformHTTPRedirection):
(WebKit::NetworkProcessProxy::resourceLoadDidReceiveChallenge):
(WebKit::NetworkProcessProxy::resourceLoadDidReceiveResponse):
(WebKit::NetworkProcessProxy::resourceLoadDidCompleteWithError):
(WebKit::NetworkProcessProxy::pageWillSendRequest): Deleted.
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebPageProxy.cpp:
* UIProcess/WebPageProxy.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::loadResourceSynchronously):
(WebKit::WebLoaderStrategy::startPingLoad):
* WebProcess/Network/WebResourceLoader.cpp:
(WebKit::WebResourceLoader::willSendRequest):

Tools:

Reviewed by Youenn Fablet.

* TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadDelegate.mm:
(-[TestResourceLoadDelegate webView:resourceLoad:didSendRequest:]):
(-[TestResourceLoadDelegate webView:resourceLoad:didPerformHTTPRedirection:newRequest:]):
(-[TestResourceLoadDelegate webView:resourceLoad:didReceiveChallenge:]):
(-[TestResourceLoadDelegate webView:resourceLoad:didReceiveResponse:]):
(-[TestResourceLoadDelegate webView:resourceLoad:didCompleteWithError:]):
(TEST):
(-[TestResourceLoadDelegate webView:willSendRequest:]): Deleted.
* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
* TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
(TEST):
* TestWebKitAPI/cocoa/HTTPServer.h:
(TestWebKitAPI::HTTPServer::HTTPResponse::HTTPResponse):
Add the ability to have non-200 status codes in responses.
Also switch the order of parameters to reflect the fact that header fields are sent before the body.
* TestWebKitAPI/cocoa/HTTPServer.mm:
(TestWebKitAPI::statusText):
(TestWebKitAPI::HTTPServer::respondToRequests):

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

33 files changed:
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkLoad.cpp
Source/WebKit/NetworkProcess/NetworkLoadClient.h
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
Source/WebKit/NetworkProcess/NetworkResourceLoader.h
Source/WebKit/Shared/API/APIObject.h
Source/WebKit/Shared/Cocoa/APIObject.mm
Source/WebKit/Shared/NetworkResourceLoadIdentifier.h [new file with mode: 0644]
Source/WebKit/Shared/ResourceLoadInfo.h [new file with mode: 0644]
Source/WebKit/SourcesCocoa.txt
Source/WebKit/UIProcess/API/APIResourceLoadClient.h
Source/WebKit/UIProcess/API/APIResourceLoadInfo.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadDelegate.h
Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.mm [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfoInternal.h [new file with mode: 0644]
Source/WebKit/UIProcess/Authentication/AuthenticationChallengeProxy.cpp
Source/WebKit/UIProcess/Cocoa/ResourceLoadDelegate.h
Source/WebKit/UIProcess/Cocoa/ResourceLoadDelegate.mm
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadDelegate.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm
Tools/TestWebKitAPI/cocoa/HTTPServer.h
Tools/TestWebKitAPI/cocoa/HTTPServer.mm

index b1c90f3..6a1612a 100644 (file)
@@ -1,5 +1,89 @@
 2020-01-10  Alex Christensen  <achristensen@webkit.org>
 
+        Expand _WKResourceLoadDelegate callbacks
+        https://bugs.webkit.org/show_bug.cgi?id=206037
+        <rdar://problem/57132290>
+
+        Reviewed by Youenn Fablet.
+
+        Add 5 informative delegate callbacks at these times during the loading process:
+        1. When a request is sent.
+        2. When a redirect happens.
+        3. When a challenge happens.
+        4. When a response is received.
+        5. When loading completes or fails.
+
+        As mentioned in r254183 these callbacks are only called when a _WKResourceLoadDelegate is given to a WKWebView.
+        We add a new struct ResourceLoadInfo which will need to be expanded containing currently only the load identifier.
+        Covered by new API tests which verify the validity of the sent information.
+
+        * NetworkProcess/NetworkLoad.cpp:
+        (WebKit::NetworkLoad::didReceiveChallenge):
+        * NetworkProcess/NetworkLoadClient.h:
+        (WebKit::NetworkLoadClient::didReceiveChallenge):
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::generateResourceLoadID):
+        (WebKit::NetworkResourceLoader::startNetworkLoad):
+        (WebKit::NetworkResourceLoader::resourceLoadInfo):
+        (WebKit::NetworkResourceLoader::didReceiveResponse):
+        (WebKit::NetworkResourceLoader::didFinishLoading):
+        (WebKit::NetworkResourceLoader::didFailLoading):
+        (WebKit::NetworkResourceLoader::didReceiveChallenge):
+        Add a way to send a message informing that a challenge happened with information gathered from the NetworkResourceLoader,
+        which previously was not informed of challenges because the challenges went directly from the NetworkLoad to the AuthenticationManager.
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+        (WebKit::NetworkResourceLoader::continueWillSendRequest):
+        (WebKit::m_shouldCaptureExtraNetworkLoadMetrics): Deleted.
+        * NetworkProcess/NetworkResourceLoader.h:
+        * Shared/API/APIObject.h:
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * Shared/ResourceLoadInfo.h: Added.
+        (WebKit::ResourceLoadInfo::encode const):
+        (WebKit::ResourceLoadInfo::decode):
+        * SourcesCocoa.txt:
+        * UIProcess/API/APIResourceLoadClient.h:
+        * UIProcess/API/APIResourceLoadInfo.h: Added.
+        * UIProcess/API/Cocoa/_WKResourceLoadDelegate.h:
+        * UIProcess/API/Cocoa/_WKResourceLoadInfo.h: Added.
+        * UIProcess/API/Cocoa/_WKResourceLoadInfo.mm: Added.
+        (-[_WKResourceLoadInfo dealloc]):
+        (-[_WKResourceLoadInfo resourceLoadID]):
+        (-[_WKResourceLoadInfo _apiObject]):
+        * UIProcess/API/Cocoa/_WKResourceLoadInfoInternal.h: Added.
+        * UIProcess/Authentication/AuthenticationChallengeProxy.cpp:
+        (WebKit::AuthenticationChallengeProxy::AuthenticationChallengeProxy):
+        An AuthenticationChallengeProxy was only used for challenges that needed credentials, so they wrapped a CompletionHandler.
+        This new type of informative-only challenge will be given a null CompletionHandler, which means no action can be taken.
+        * UIProcess/Cocoa/ResourceLoadDelegate.h:
+        * UIProcess/Cocoa/ResourceLoadDelegate.mm:
+        (WebKit::ResourceLoadDelegate::setDelegate):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::didSendRequest const):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::didPerformHTTPRedirection const):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::didReceiveChallenge const):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::didReceiveResponse const):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::didCompleteWithError const):
+        (WebKit::ResourceLoadDelegate::ResourceLoadClient::willSendRequest const): Deleted.
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::resourceLoadDidSendRequest):
+        (WebKit::NetworkProcessProxy::resourceLoadDidPerformHTTPRedirection):
+        (WebKit::NetworkProcessProxy::resourceLoadDidReceiveChallenge):
+        (WebKit::NetworkProcessProxy::resourceLoadDidReceiveResponse):
+        (WebKit::NetworkProcessProxy::resourceLoadDidCompleteWithError):
+        (WebKit::NetworkProcessProxy::pageWillSendRequest): Deleted.
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebPageProxy.cpp:
+        * UIProcess/WebPageProxy.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::loadResourceSynchronously):
+        (WebKit::WebLoaderStrategy::startPingLoad):
+        * WebProcess/Network/WebResourceLoader.cpp:
+        (WebKit::WebResourceLoader::willSendRequest):
+
+2020-01-10  Alex Christensen  <achristensen@webkit.org>
+
         Add SPI to enable TLS 1.0 and 1.1 in WKWebViews
         https://bugs.webkit.org/show_bug.cgi?id=206046
 
index f9316a6..30aca1f 100644 (file)
@@ -189,6 +189,8 @@ void NetworkLoad::willPerformHTTPRedirection(ResourceResponse&& redirectResponse
 
 void NetworkLoad::didReceiveChallenge(AuthenticationChallenge&& challenge, ChallengeCompletionHandler&& completionHandler)
 {
+    m_client.get().didReceiveChallenge(challenge);
+
     auto scheme = challenge.protectionSpace().authenticationScheme();
     bool isTLSHandshake = scheme == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested
         || scheme == ProtectionSpaceAuthenticationSchemeClientCertificateRequested;
index 18ec0c5..0a5f66b 100644 (file)
@@ -30,6 +30,7 @@
 #include <WebCore/ResourceResponse.h>
 
 namespace WebCore {
+class AuthenticationChallenge;
 class NetworkLoadMetrics;
 class SharedBuffer;
 enum class PolicyAction : uint8_t;
@@ -54,6 +55,7 @@ public:
     virtual void didFinishLoading(const WebCore::NetworkLoadMetrics&) = 0;
     virtual void didFailLoading(const WebCore::ResourceError&) = 0;
     virtual void didBlockAuthenticationChallenge() { };
+    virtual void didReceiveChallenge(const WebCore::AuthenticationChallenge&) { };
     virtual bool shouldCaptureExtraNetworkLoadMetrics() const { return false; }
 };
 
index df09f64..2113c47 100644 (file)
@@ -39,6 +39,7 @@
 #include "NetworkProcessConnectionMessages.h"
 #include "NetworkProcessProxyMessages.h"
 #include "NetworkSession.h"
+#include "ResourceLoadInfo.h"
 #include "ServiceWorkerFetchTask.h"
 #include "SharedBufferDataReference.h"
 #include "WebCoreArgumentCoders.h"
@@ -104,6 +105,7 @@ NetworkResourceLoader::NetworkResourceLoader(NetworkResourceLoadParameters&& par
     , m_isAllowedToAskUserForCredentials { m_parameters.clientCredentialPolicy == ClientCredentialPolicy::MayAskClientForCredentials }
     , m_bufferingTimer { *this, &NetworkResourceLoader::bufferingTimerFired }
     , m_shouldCaptureExtraNetworkLoadMetrics(m_connection->captureExtraNetworkLoadMetricsEnabled())
+    , m_resourceLoadID { NetworkResourceLoadIdentifier::generate() }
 {
     ASSERT(RunLoop::isMain());
 
@@ -323,7 +325,7 @@ void NetworkResourceLoader::startNetworkLoad(ResourceRequest&& request, FirstLoa
         parameters.blobFileReferences = networkSession->blobRegistry().filesInBlob(originalRequest().url());
 
     if (m_parameters.pageHasResourceLoadClient)
-        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::PageWillSendRequest(m_parameters.webPageProxyID, request), 0);
+        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidSendRequest(m_parameters.webPageProxyID, resourceLoadInfo(), request), 0);
 
     parameters.request = WTFMove(request);
     m_networkLoad = makeUnique<NetworkLoad>(*this, &networkSession->blobRegistry(), WTFMove(parameters), *networkSession);
@@ -331,6 +333,13 @@ void NetworkResourceLoader::startNetworkLoad(ResourceRequest&& request, FirstLoa
     RELEASE_LOG_IF_ALLOWED("startNetworkLoad: Going to the network (description=%{public}s)", m_networkLoad->description().utf8().data());
 }
 
+ResourceLoadInfo NetworkResourceLoader::resourceLoadInfo()
+{
+    return {
+        m_resourceLoadID
+    };
+}
+
 void NetworkResourceLoader::cleanup(LoadResult result)
 {
     ASSERT(RunLoop::isMain());
@@ -547,6 +556,9 @@ void NetworkResourceLoader::didReceiveResponse(ResourceResponse&& receivedRespon
     RELEASE_LOG_IF_ALLOWED("didReceiveResponse: Sending WebResourceLoader::DidReceiveResponse IPC (willWaitForContinueDidReceiveResponse=%d)", willWaitForContinueDidReceiveResponse);
     send(Messages::WebResourceLoader::DidReceiveResponse { response, willWaitForContinueDidReceiveResponse });
 
+    if (m_parameters.pageHasResourceLoadClient)
+        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidReceiveResponse(m_parameters.webPageProxyID, resourceLoadInfo(), response), 0);
+
     if (willWaitForContinueDidReceiveResponse) {
         m_responseCompletionHandler = WTFMove(completionHandler);
         return;
@@ -623,6 +635,9 @@ void NetworkResourceLoader::didFinishLoading(const NetworkLoadMetrics& networkLo
 
     tryStoreAsCacheEntry();
 
+    if (m_parameters.pageHasResourceLoadClient)
+        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidCompleteWithError(m_parameters.webPageProxyID, resourceLoadInfo(), { }), 0);
+
     cleanup(LoadResult::Success);
 }
 
@@ -655,6 +670,9 @@ void NetworkResourceLoader::didFailLoading(const ResourceError& error)
 #endif
     }
 
+    if (m_parameters.pageHasResourceLoadClient)
+        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidCompleteWithError(m_parameters.webPageProxyID, resourceLoadInfo(), error), 0);
+
     cleanup(LoadResult::Failure);
 }
 
@@ -664,6 +682,12 @@ void NetworkResourceLoader::didBlockAuthenticationChallenge()
     send(Messages::WebResourceLoader::DidBlockAuthenticationChallenge());
 }
 
+void NetworkResourceLoader::didReceiveChallenge(const AuthenticationChallenge& challenge)
+{
+    if (m_parameters.pageHasResourceLoadClient)
+        m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidReceiveChallenge(m_parameters.webPageProxyID, resourceLoadInfo(), challenge), 0);
+}
+
 Optional<Seconds> NetworkResourceLoader::validateCacheEntryForMaxAgeCapValidation(const ResourceRequest& request, const ResourceRequest& redirectRequest, const ResourceResponse& redirectResponse)
 {
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
@@ -690,6 +714,7 @@ void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request,
 {
     RELEASE_LOG_IF_ALLOWED("willSendRedirectedRequest:");
     ++m_redirectCount;
+    m_redirectResponse = redirectResponse;
 
     Optional<AdClickAttribution::Conversion> adClickConversion;
     if (!sessionID().isEphemeral())
@@ -865,6 +890,10 @@ void NetworkResourceLoader::continueWillSendRequest(ResourceRequest&& newRequest
 
     if (m_networkLoad) {
         RELEASE_LOG_IF_ALLOWED("continueWillSendRequest: Telling NetworkLoad to proceed with the redirect");
+
+        if (m_parameters.pageHasResourceLoadClient && !newRequest.isNull())
+            m_connection->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::ResourceLoadDidPerformHTTPRedirection(m_parameters.webPageProxyID, resourceLoadInfo(), m_redirectResponse, newRequest), 0);
+
         m_networkLoad->continueWillSendRequest(WTFMove(newRequest));
     }
 }
index 0a8cc4b..151b48c 100644 (file)
@@ -31,6 +31,7 @@
 #include "NetworkConnectionToWebProcess.h"
 #include "NetworkConnectionToWebProcessMessagesReplies.h"
 #include "NetworkLoadClient.h"
+#include "NetworkResourceLoadIdentifier.h"
 #include "NetworkResourceLoadParameters.h"
 #include <WebCore/AdClickAttribution.h>
 #include <WebCore/ContentSecurityPolicyClient.h>
@@ -54,6 +55,8 @@ class NetworkLoadChecker;
 class ServiceWorkerFetchTask;
 class WebSWServerConnection;
 
+struct ResourceLoadInfo;
+
 namespace NetworkCache {
 class Entry;
 }
@@ -97,16 +100,17 @@ public:
     struct SynchronousLoadData;
 
     // NetworkLoadClient.
-    void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
-    bool isSynchronous() const override;
-    bool isAllowedToAskUserForCredentials() const override { return m_isAllowedToAskUserForCredentials; }
-    void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&&) override;
-    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) override;
-    void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) override;
-    void didFinishLoading(const WebCore::NetworkLoadMetrics&) override;
-    void didFailLoading(const WebCore::ResourceError&) override;
-    void didBlockAuthenticationChallenge() override;
-    bool shouldCaptureExtraNetworkLoadMetrics() const override;
+    void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final;
+    bool isSynchronous() const final;
+    bool isAllowedToAskUserForCredentials() const final { return m_isAllowedToAskUserForCredentials; }
+    void willSendRedirectedRequest(WebCore::ResourceRequest&&, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&&) final;
+    void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
+    void didReceiveBuffer(Ref<WebCore::SharedBuffer>&&, int reportedEncodedDataLength) final;
+    void didFinishLoading(const WebCore::NetworkLoadMetrics&) final;
+    void didFailLoading(const WebCore::ResourceError&) final;
+    void didBlockAuthenticationChallenge() final;
+    void didReceiveChallenge(const WebCore::AuthenticationChallenge&) final;
+    bool shouldCaptureExtraNetworkLoadMetrics() const final;
 
     void convertToDownload(DownloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
 
@@ -195,6 +199,8 @@ private:
 
     Optional<Seconds> validateCacheEntryForMaxAgeCapValidation(const WebCore::ResourceRequest&, const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse&);
 
+    ResourceLoadInfo resourceLoadInfo();
+
     const NetworkResourceLoadParameters m_parameters;
 
     Ref<NetworkConnectionToWebProcess> m_connection;
@@ -234,6 +240,8 @@ private:
 #if ENABLE(SERVICE_WORKER)
     std::unique_ptr<ServiceWorkerFetchTask> m_serviceWorkerFetchTask;
 #endif
+    NetworkResourceLoadIdentifier m_resourceLoadID;
+    WebCore::ResourceResponse m_redirectResponse;
 };
 
 } // namespace WebKit
index 8b71fe0..fdb81f4 100644 (file)
@@ -71,6 +71,7 @@ public:
         ProtectionSpace,
         RenderLayer,
         RenderObject,
+        ResourceLoadInfo,
         SecurityOrigin,
         SessionState,
         SerializedScriptValue,
index db65e6f..642f6ef 100644 (file)
@@ -81,6 +81,7 @@
 #import "_WKInspectorInternal.h"
 #import "_WKInternalDebugFeatureInternal.h"
 #import "_WKProcessPoolConfigurationInternal.h"
+#import "_WKResourceLoadInfoInternal.h"
 #import "_WKResourceLoadStatisticsFirstPartyInternal.h"
 #import "_WKResourceLoadStatisticsThirdPartyInternal.h"
 #import "_WKUserContentWorldInternal.h"
@@ -332,6 +333,10 @@ void* Object::newObject(size_t size, Type type)
         wrapper = [_WKCustomHeaderFields alloc];
         break;
 
+    case Type::ResourceLoadInfo:
+        wrapper = [_WKResourceLoadInfo alloc];
+        break;
+            
     case Type::ResourceLoadStatisticsFirstParty:
         wrapper = [_WKResourceLoadStatisticsFirstParty alloc];
         break;
diff --git a/Source/WebKit/Shared/NetworkResourceLoadIdentifier.h b/Source/WebKit/Shared/NetworkResourceLoadIdentifier.h
new file mode 100644 (file)
index 0000000..5bd844c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/ObjectIdentifier.h>
+
+namespace WebKit {
+
+enum NetworkResourceLoadIdentifierType { };
+using NetworkResourceLoadIdentifier = ObjectIdentifier<NetworkResourceLoadIdentifierType>;
+
+}
diff --git a/Source/WebKit/Shared/ResourceLoadInfo.h b/Source/WebKit/Shared/ResourceLoadInfo.h
new file mode 100644 (file)
index 0000000..e1db881
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ArgumentCoders.h"
+#include "NetworkResourceLoadIdentifier.h"
+
+namespace WebKit {
+
+struct ResourceLoadInfo {
+
+    NetworkResourceLoadIdentifier resourceLoadID;
+    
+    void encode(IPC::Encoder& encoder) const
+    {
+        encoder << resourceLoadID;
+    }
+
+    static Optional<ResourceLoadInfo> decode(IPC::Decoder& decoder)
+    {
+        Optional<NetworkResourceLoadIdentifier> resourceLoadID;
+        decoder >> resourceLoadID;
+        if (!resourceLoadID)
+            return WTF::nullopt;
+
+        return {{
+            WTFMove(*resourceLoadID),
+        }};
+    }
+};
+
+} // namespace WebKit
index 939fb17..e9fb4d5 100644 (file)
@@ -264,6 +264,7 @@ UIProcess/API/Cocoa/_WKInternalDebugFeature.mm
 UIProcess/API/Cocoa/_WKLinkIconParameters.mm
 UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm
 UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
+UIProcess/API/Cocoa/_WKResourceLoadInfo.mm
 UIProcess/API/Cocoa/_WKSessionState.mm
 UIProcess/API/Cocoa/_WKTextInputContext.mm
 UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm
index 6a0d6ad..2181d8d 100644 (file)
 
 #pragma once
 
+namespace WebKit {
+class AuthenticationChallengeProxy;
+struct ResourceLoadInfo;
+}
+
 namespace API {
 
 class ResourceLoadClient {
 public:
     virtual ~ResourceLoadClient() = default;
 
-    virtual void willSendRequest(const WebCore::ResourceRequest&) const = 0;
+    virtual void didSendRequest(WebKit::ResourceLoadInfo&&, WebCore::ResourceRequest&&) const = 0;
+    virtual void didPerformHTTPRedirection(WebKit::ResourceLoadInfo&&, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&) const = 0;
+    virtual void didReceiveChallenge(WebKit::ResourceLoadInfo&&, WebKit::AuthenticationChallengeProxy&) const = 0;
+    virtual void didReceiveResponse(WebKit::ResourceLoadInfo&&, WebCore::ResourceResponse&&) const = 0;
+    virtual void didCompleteWithError(WebKit::ResourceLoadInfo&&, WebCore::ResourceError&&) const = 0;
 };
 
 } // namespace API
diff --git a/Source/WebKit/UIProcess/API/APIResourceLoadInfo.h b/Source/WebKit/UIProcess/API/APIResourceLoadInfo.h
new file mode 100644 (file)
index 0000000..b73978e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "APIObject.h"
+#include "ResourceLoadInfo.h"
+
+namespace API {
+
+class ResourceLoadInfo final : public ObjectImpl<Object::Type::ResourceLoadInfo> {
+public:
+    static Ref<ResourceLoadInfo> create(WebKit::ResourceLoadInfo&& info)
+    {
+        return adoptRef(*new ResourceLoadInfo(WTFMove(info)));
+    }
+
+    WebKit::NetworkResourceLoadIdentifier resourceLoadID() const { return m_info.resourceLoadID; }
+
+private:
+    explicit ResourceLoadInfo(WebKit::ResourceLoadInfo&& info)
+        : m_info(WTFMove(info))
+    {
+    }
+
+    const WebKit::ResourceLoadInfo m_info;
+
+};
+
+} // namespace API
index 97320fb..fcc13ed 100644 (file)
 
 #import <WebKit/WKFoundation.h>
 
+@class _WKResourceLoadInfo;
+
 NS_ASSUME_NONNULL_BEGIN
 
 WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
 @protocol _WKResourceLoadDelegate <NSObject>
 @optional
 
-- (void)webView:(WKWebView *)webView willSendRequest:(NSURLRequest *)request;
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didSendRequest:(NSURLRequest *)request;
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didPerformHTTPRedirection:(NSURLResponse *)response newRequest:(NSURLRequest *)request;
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge;
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didReceiveResponse:(NSURLResponse *)response;
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didCompleteWithError:(NSError * __nullable)error;
 
 @end
 
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.h b/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.h
new file mode 100644 (file)
index 0000000..f273480
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+NS_ASSUME_NONNULL_BEGIN
+
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKResourceLoadInfo : NSObject
+
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)init NS_UNAVAILABLE;
+
+@property (nonatomic, readonly) uint64_t resourceLoadID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfo.mm
new file mode 100644 (file)
index 0000000..617fc54
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "_WKResourceLoadInfo.h"
+
+#import "APIResourceLoadInfo.h"
+#import "_WKResourceLoadInfoInternal.h"
+
+@implementation _WKResourceLoadInfo
+
+- (void)dealloc
+{
+    _info->API::ResourceLoadInfo::~ResourceLoadInfo();
+    [super dealloc];
+}
+
+- (uint64_t)resourceLoadID
+{
+    return _info->resourceLoadID().toUInt64();
+}
+
+- (API::Object&)_apiObject
+{
+    return *_info;
+}
+
+@end
+
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfoInternal.h b/Source/WebKit/UIProcess/API/Cocoa/_WKResourceLoadInfoInternal.h
new file mode 100644 (file)
index 0000000..773a274
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "APIResourceLoadInfo.h"
+#import "WKObject.h"
+#import "_WKResourceLoadInfo.h"
+
+namespace WebKit {
+
+template<> struct WrapperTraits<API::ResourceLoadInfo> {
+    using WrapperClass = _WKResourceLoadInfo;
+};
+
+}
+
+@interface _WKResourceLoadInfo () <WKObject> {
+@package
+    API::ObjectStorage<API::ResourceLoadInfo> _info;
+}
+@end
index d9c4173..40dd643 100644 (file)
@@ -45,7 +45,7 @@ namespace WebKit {
 
 AuthenticationChallengeProxy::AuthenticationChallengeProxy(WebCore::AuthenticationChallenge&& authenticationChallenge, uint64_t challengeID, Ref<IPC::Connection>&& connection, WeakPtr<SecKeyProxyStore>&& secKeyProxyStore)
     : m_coreAuthenticationChallenge(WTFMove(authenticationChallenge))
-    , m_listener(AuthenticationDecisionListener::create([challengeID, connection = WTFMove(connection), secKeyProxyStore = WTFMove(secKeyProxyStore)](AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) {
+    , m_listener(AuthenticationDecisionListener::create(challengeID ? CompletionHandler<void(AuthenticationChallengeDisposition, const WebCore::Credential&)>([challengeID, connection = WTFMove(connection), secKeyProxyStore = WTFMove(secKeyProxyStore)](AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) {
 #if HAVE(SEC_KEY_PROXY)
         if (secKeyProxyStore && secKeyProxyStore->initialize(credential)) {
             sendClientCertificateCredentialOverXpc(connection, *secKeyProxyStore, challengeID, credential);
@@ -53,7 +53,7 @@ AuthenticationChallengeProxy::AuthenticationChallengeProxy(WebCore::Authenticati
         }
 #endif
         connection->send(Messages::AuthenticationManager::CompleteAuthenticationChallenge(challengeID, disposition, credential), 0);
-    }))
+    }) : nullptr))
 {
 }
 
index 985d24c..e835304 100644 (file)
@@ -57,7 +57,11 @@ private:
 
     private:
         // API::ResourceLoadClient
-        void willSendRequest(const WebCore::ResourceRequest&) const final;
+        void didSendRequest(ResourceLoadInfo&&, WebCore::ResourceRequest&&) const final;
+        void didPerformHTTPRedirection(ResourceLoadInfo&&, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&) const final;
+        void didReceiveChallenge(ResourceLoadInfo&&, WebKit::AuthenticationChallengeProxy&) const final;
+        void didReceiveResponse(ResourceLoadInfo&&, WebCore::ResourceResponse&&) const final;
+        void didCompleteWithError(ResourceLoadInfo&&, WebCore::ResourceError&&) const final;
 
         ResourceLoadDelegate& m_resourceLoadDelegate;
     };
@@ -66,7 +70,11 @@ private:
     WeakObjCPtr<id <_WKResourceLoadDelegate> > m_delegate;
 
     struct {
-        bool willSendRequest : 1;
+        bool didSendRequest : 1;
+        bool didPerformHTTPRedirection : 1;
+        bool didReceiveChallenge : 1;
+        bool didReceiveResponse : 1;
+        bool didCompleteWithError : 1;
     } m_delegateMethods;
 };
 
index 6bf675a..6b7800b 100644 (file)
@@ -27,6 +27,7 @@
 #import "ResourceLoadDelegate.h"
 
 #import "_WKResourceLoadDelegate.h"
+#import "_WKResourceLoadInfoInternal.h"
 
 namespace WebKit {
 
@@ -51,7 +52,16 @@ void ResourceLoadDelegate::setDelegate(id <_WKResourceLoadDelegate> delegate)
 {
     m_delegate = delegate;
 
-    m_delegateMethods.willSendRequest = [delegate respondsToSelector:@selector(webView:willSendRequest:)];
+    // resourceWithID:
+    // type:
+    // _WKFrameHandle frame:
+    // _WKFrameHandle parentFrame:
+    
+    m_delegateMethods.didSendRequest = [delegate respondsToSelector:@selector(webView:resourceLoad:didSendRequest:)];
+    m_delegateMethods.didPerformHTTPRedirection = [delegate respondsToSelector:@selector(webView:resourceLoad:didPerformHTTPRedirection:newRequest:)];
+    m_delegateMethods.didReceiveChallenge = [delegate respondsToSelector:@selector(webView:resourceLoad:didReceiveChallenge:)];
+    m_delegateMethods.didReceiveResponse = [delegate respondsToSelector:@selector(webView:resourceLoad:didReceiveResponse:)];
+    m_delegateMethods.didCompleteWithError = [delegate respondsToSelector:@selector(webView:resourceLoad:didCompleteWithError:)];
 }
 
 ResourceLoadDelegate::ResourceLoadClient::ResourceLoadClient(ResourceLoadDelegate& delegate)
@@ -61,16 +71,64 @@ ResourceLoadDelegate::ResourceLoadClient::ResourceLoadClient(ResourceLoadDelegat
 
 ResourceLoadDelegate::ResourceLoadClient::~ResourceLoadClient() = default;
 
-void ResourceLoadDelegate::ResourceLoadClient::willSendRequest(const WebCore::ResourceRequest& request) const
+void ResourceLoadDelegate::ResourceLoadClient::didSendRequest(WebKit::ResourceLoadInfo&& loadInfo, WebCore::ResourceRequest&& request) const
 {
-    if (!m_resourceLoadDelegate.m_delegateMethods.willSendRequest)
+    if (!m_resourceLoadDelegate.m_delegateMethods.didSendRequest)
         return;
 
     auto delegate = m_resourceLoadDelegate.m_delegate.get();
     if (!delegate)
         return;
 
-    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() willSendRequest:request.nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)];
+    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() resourceLoad:wrapper(API::ResourceLoadInfo::create(WTFMove(loadInfo)).get()) didSendRequest:request.nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)];
+}
+
+void ResourceLoadDelegate::ResourceLoadClient::didPerformHTTPRedirection(WebKit::ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request) const
+{
+    if (!m_resourceLoadDelegate.m_delegateMethods.didPerformHTTPRedirection)
+        return;
+
+    auto delegate = m_resourceLoadDelegate.m_delegate.get();
+    if (!delegate)
+        return;
+
+    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() resourceLoad:wrapper(API::ResourceLoadInfo::create(WTFMove(loadInfo)).get()) didPerformHTTPRedirection:response.nsURLResponse() newRequest:request.nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)];
+}
+
+void ResourceLoadDelegate::ResourceLoadClient::didReceiveChallenge(WebKit::ResourceLoadInfo&& loadInfo, WebKit::AuthenticationChallengeProxy& challenge) const
+{
+    if (!m_resourceLoadDelegate.m_delegateMethods.didReceiveChallenge)
+        return;
+
+    auto delegate = m_resourceLoadDelegate.m_delegate.get();
+    if (!delegate)
+        return;
+
+    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() resourceLoad:wrapper(API::ResourceLoadInfo::create(WTFMove(loadInfo)).get()) didReceiveChallenge:wrapper(challenge)];
+}
+
+void ResourceLoadDelegate::ResourceLoadClient::didReceiveResponse(WebKit::ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response) const
+{
+    if (!m_resourceLoadDelegate.m_delegateMethods.didReceiveResponse)
+        return;
+
+    auto delegate = m_resourceLoadDelegate.m_delegate.get();
+    if (!delegate)
+        return;
+
+    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() resourceLoad:wrapper(API::ResourceLoadInfo::create(WTFMove(loadInfo)).get()) didReceiveResponse:response.nsURLResponse()];
+}
+
+void ResourceLoadDelegate::ResourceLoadClient::didCompleteWithError(WebKit::ResourceLoadInfo&& loadInfo, WebCore::ResourceError&& error) const
+{
+    if (!m_resourceLoadDelegate.m_delegateMethods.didCompleteWithError)
+        return;
+
+    auto delegate = m_resourceLoadDelegate.m_delegate.get();
+    if (!delegate)
+        return;
+
+    [delegate webView:m_resourceLoadDelegate.m_webView.get().get() resourceLoad:wrapper(API::ResourceLoadInfo::create(WTFMove(loadInfo)).get()) didCompleteWithError:error.nsError()];
 }
 
 } // namespace WebKit
index 602f9c0..0cf0de0 100644 (file)
@@ -452,13 +452,50 @@ void NetworkProcessProxy::logGlobalDiagnosticMessageWithValue(const String& mess
         page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample);
 }
 
-void NetworkProcessProxy::pageWillSendRequest(WebPageProxyIdentifier pageID, const WebCore::ResourceRequest& request)
+void NetworkProcessProxy::resourceLoadDidSendRequest(WebPageProxyIdentifier pageID, ResourceLoadInfo&& loadInfo, WebCore::ResourceRequest&& request)
 {
     auto* page = WebProcessProxy::webPage(pageID);
     if (!page)
         return;
 
-    page->willSendRequest(request);
+    page->resourceLoadDidSendRequest(WTFMove(loadInfo), WTFMove(request));
+}
+
+void NetworkProcessProxy::resourceLoadDidPerformHTTPRedirection(WebPageProxyIdentifier pageID, ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request)
+{
+    auto* page = WebProcessProxy::webPage(pageID);
+    if (!page)
+        return;
+
+    page->resourceLoadDidPerformHTTPRedirection(WTFMove(loadInfo), WTFMove(response), WTFMove(request));
+}
+
+void NetworkProcessProxy::resourceLoadDidReceiveChallenge(WebPageProxyIdentifier pageID, ResourceLoadInfo&& loadInfo, WebCore::AuthenticationChallenge&& challenge)
+{
+    auto* page = WebProcessProxy::webPage(pageID);
+    if (!page)
+        return;
+
+    auto challengeProxy = AuthenticationChallengeProxy::create(WTFMove(challenge), 0, *connection(), nullptr);
+    page->resourceLoadDidReceiveChallenge(WTFMove(loadInfo), challengeProxy.get());
+}
+
+void NetworkProcessProxy::resourceLoadDidReceiveResponse(WebPageProxyIdentifier pageID, ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response)
+{
+    auto* page = WebProcessProxy::webPage(pageID);
+    if (!page)
+        return;
+
+    page->resourceLoadDidReceiveResponse(WTFMove(loadInfo), WTFMove(response));
+}
+
+void NetworkProcessProxy::resourceLoadDidCompleteWithError(WebPageProxyIdentifier pageID, ResourceLoadInfo&& loadInfo, WebCore::ResourceError&& error)
+{
+    auto* page = WebProcessProxy::webPage(pageID);
+    if (!page)
+        return;
+
+    page->resourceLoadDidCompleteWithError(WTFMove(loadInfo), WTFMove(error));
 }
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
index 8dcab64..74c762a 100644 (file)
@@ -64,12 +64,15 @@ namespace WebKit {
 class DownloadProxy;
 class DownloadProxyMap;
 class WebProcessPool;
+class WebUserContentControllerProxy;
+
 enum class ShouldGrandfatherStatistics : bool;
 enum class StorageAccessStatus : uint8_t;
 enum class WebsiteDataFetchOption;
 enum class WebsiteDataType;
+
 struct NetworkProcessCreationParameters;
-class WebUserContentControllerProxy;
+struct ResourceLoadInfo;
 struct WebsiteData;
 
 class NetworkProcessProxy final : public AuxiliaryProcessProxy, private ProcessThrottlerClient, public CanMakeWeakPtr<NetworkProcessProxy> {
@@ -201,7 +204,11 @@ public:
 
     void resetQuota(PAL::SessionID, CompletionHandler<void()>&&);
 
-    void pageWillSendRequest(WebPageProxyIdentifier, const WebCore::ResourceRequest&);
+    void resourceLoadDidSendRequest(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceRequest&&);
+    void resourceLoadDidPerformHTTPRedirection(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
+    void resourceLoadDidReceiveChallenge(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::AuthenticationChallenge&&);
+    void resourceLoadDidReceiveResponse(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceResponse&&);
+    void resourceLoadDidCompleteWithError(WebPageProxyIdentifier, ResourceLoadInfo&&, WebCore::ResourceError&&);
 
 private:
     // AuxiliaryProcessProxy
index 33a80ed..da9709b 100644 (file)
@@ -68,5 +68,9 @@ messages -> NetworkProcessProxy LegacyReceiver NotRefCounted {
 
     RequestStorageSpace(PAL::SessionID sessionID, struct WebCore::ClientOrigin origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired) -> (Optional<uint64_t> newQuota) Async
     
-    PageWillSendRequest(WebKit::WebPageProxyIdentifier pageIdentifier, WebCore::ResourceRequest request)
+    ResourceLoadDidSendRequest(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceRequest request)
+    ResourceLoadDidPerformHTTPRedirection(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceResponse resourceResponse, WebCore::ResourceRequest request)
+    ResourceLoadDidReceiveChallenge(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::AuthenticationChallenge challenge)
+    ResourceLoadDidReceiveResponse(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceResponse response)
+    ResourceLoadDidCompleteWithError(WebKit::WebPageProxyIdentifier pageIdentifier, struct WebKit::ResourceLoadInfo resourceLoadInfo, WebCore::ResourceError error)
 }
index 773fa98..bb1201d 100644 (file)
@@ -5921,10 +5921,34 @@ WebInspectorProxy* WebPageProxy::inspector() const
     return m_inspector.get();
 }
 
-void WebPageProxy::willSendRequest(const WebCore::ResourceRequest& request)
+void WebPageProxy::resourceLoadDidSendRequest(ResourceLoadInfo&& loadInfo, WebCore::ResourceRequest&& request)
 {
     if (m_resourceLoadClient)
-        m_resourceLoadClient->willSendRequest(request);
+        m_resourceLoadClient->didSendRequest(WTFMove(loadInfo), WTFMove(request));
+}
+
+void WebPageProxy::resourceLoadDidPerformHTTPRedirection(ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response, WebCore::ResourceRequest&& request)
+{
+    if (m_resourceLoadClient)
+        m_resourceLoadClient->didPerformHTTPRedirection(WTFMove(loadInfo), WTFMove(response), WTFMove(request));
+}
+
+void WebPageProxy::resourceLoadDidReceiveChallenge(ResourceLoadInfo&& loadInfo, WebKit::AuthenticationChallengeProxy& challenge)
+{
+    if (m_resourceLoadClient)
+        m_resourceLoadClient->didReceiveChallenge(WTFMove(loadInfo), challenge);
+}
+
+void WebPageProxy::resourceLoadDidReceiveResponse(ResourceLoadInfo&& loadInfo, WebCore::ResourceResponse&& response)
+{
+    if (m_resourceLoadClient)
+        m_resourceLoadClient->didReceiveResponse(WTFMove(loadInfo), WTFMove(response));
+}
+
+void WebPageProxy::resourceLoadDidCompleteWithError(ResourceLoadInfo&& loadInfo, WebCore::ResourceError&& error)
+{
+    if (m_resourceLoadClient)
+        m_resourceLoadClient->didCompleteWithError(WTFMove(loadInfo), WTFMove(error));
 }
 
 #if ENABLE(FULLSCREEN_API)
index 4ff6dc2..9144e68 100644 (file)
@@ -325,6 +325,7 @@ struct NavigationActionData;
 struct PlatformPopupMenuData;
 struct PrintInfo;
 struct PDFContextMenu;
+struct ResourceLoadInfo;
 struct WebAutocorrectionData;
 struct WebHitTestResultData;
 struct WebNavigationDataStore;
@@ -470,7 +471,11 @@ public:
 
     WebInspectorProxy* inspector() const;
 
-    void willSendRequest(const WebCore::ResourceRequest&);
+    void resourceLoadDidSendRequest(ResourceLoadInfo&&, WebCore::ResourceRequest&&);
+    void resourceLoadDidPerformHTTPRedirection(ResourceLoadInfo&&, WebCore::ResourceResponse&&, WebCore::ResourceRequest&&);
+    void resourceLoadDidReceiveChallenge(ResourceLoadInfo&&, WebKit::AuthenticationChallengeProxy&);
+    void resourceLoadDidReceiveResponse(ResourceLoadInfo&&, WebCore::ResourceResponse&&);
+    void resourceLoadDidCompleteWithError(ResourceLoadInfo&&, WebCore::ResourceError&&);
 
     void didChangeInspectorFrontendCount(unsigned count) { m_inspectorFrontendCount = count; }
     unsigned inspectorFrontendCount() const { return m_inspectorFrontendCount; }
index 4736239..4dac1de 100644 (file)
@@ -48,6 +48,7 @@
 #import "RemoteLayerTreeTransaction.h"
 #import "RemoteScrollingCoordinatorProxy.h"
 #import "ShareableResource.h"
+#import "UIKitSPI.h"
 #import "UserData.h"
 #import "UserInterfaceIdiom.h"
 #import "VersionChecks.h"
index a35f4df..9764c6f 100644 (file)
                5CB2378C1DF0DE6E00117AA3 /* _WKWebsitePolicies.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB237891DF0DD4300117AA3 /* _WKWebsitePolicies.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5CB2378E1DF0E0D300117AA3 /* _WKWebsitePoliciesInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB2378D1DF0E0C200117AA3 /* _WKWebsitePoliciesInternal.h */; };
                5CB7AFE023C52CE500E49CF3 /* _WKResourceLoadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB7AFDF23C52CBC00E49CF3 /* _WKResourceLoadDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               5CB7AFE723C6820700E49CF3 /* ResourceLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB7AFE623C681B000E49CF3 /* ResourceLoadInfo.h */; };
+               5CB7AFE823C69B6100E49CF3 /* _WKResourceLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CB7AFE323C67D3700E49CF3 /* _WKResourceLoadInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5CBC9B8E1C652CA000A8FDCF /* NetworkDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBC9B891C6524A500A8FDCF /* NetworkDataTask.h */; };
                5CBD595C2280EDF4002B22AA /* _WKCustomHeaderFields.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C5D2388227A1892000B9BDA /* _WKCustomHeaderFields.mm */; };
                5CD286511E7235990094FDC8 /* WKContentRuleListStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CD2864D1E722F440094FDC8 /* WKContentRuleListStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
                5CB7AFDD23C5273D00E49CF3 /* ResourceLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadDelegate.h; sourceTree = "<group>"; };
                5CB7AFDE23C5273D00E49CF3 /* ResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoadDelegate.mm; sourceTree = "<group>"; };
                5CB7AFDF23C52CBC00E49CF3 /* _WKResourceLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKResourceLoadDelegate.h; sourceTree = "<group>"; };
+               5CB7AFE223C67D3700E49CF3 /* _WKResourceLoadInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKResourceLoadInfo.mm; sourceTree = "<group>"; };
+               5CB7AFE323C67D3700E49CF3 /* _WKResourceLoadInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKResourceLoadInfo.h; sourceTree = "<group>"; };
+               5CB7AFE423C67D6400E49CF3 /* APIResourceLoadInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIResourceLoadInfo.h; sourceTree = "<group>"; };
+               5CB7AFE523C67DF900E49CF3 /* _WKResourceLoadInfoInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKResourceLoadInfoInternal.h; sourceTree = "<group>"; };
+               5CB7AFE623C681B000E49CF3 /* ResourceLoadInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadInfo.h; sourceTree = "<group>"; };
                5CBC9B891C6524A500A8FDCF /* NetworkDataTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkDataTask.h; sourceTree = "<group>"; };
                5CBC9B8B1C65257300A8FDCF /* NetworkDataTaskCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkDataTaskCocoa.mm; sourceTree = "<group>"; };
                5CC5DB9121488E16006CB8A8 /* SharedBufferDataReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferDataReference.h; sourceTree = "<group>"; };
                5CD2864E1E722F440094FDC8 /* WKContentRuleListStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKContentRuleListStore.mm; sourceTree = "<group>"; };
                5CD2864F1E722F440094FDC8 /* WKContentRuleListStoreInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentRuleListStoreInternal.h; sourceTree = "<group>"; };
                5CD286501E722F440094FDC8 /* WKContentRuleListStorePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentRuleListStorePrivate.h; sourceTree = "<group>"; };
+               5CD748B523C8EB190092A9B5 /* NetworkResourceLoadIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkResourceLoadIdentifier.h; sourceTree = "<group>"; };
                5CE0C366229F2D3D003695F0 /* APIContextMenuElementInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIContextMenuElementInfo.cpp; sourceTree = "<group>"; };
                5CE0C367229F2D3E003695F0 /* APIContextMenuElementInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIContextMenuElementInfo.h; sourceTree = "<group>"; };
                5CE0C368229F2D4A003695F0 /* WKContextMenuElementInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKContextMenuElementInfo.mm; sourceTree = "<group>"; };
                                DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */,
                                1ADCB868189831B30022EE5A /* NavigationActionData.cpp */,
                                1ADCB869189831B30022EE5A /* NavigationActionData.h */,
+                               5CD748B523C8EB190092A9B5 /* NetworkResourceLoadIdentifier.h */,
                                9BC59D6D1EFCDC6D001E8D09 /* OptionalCallbackID.h */,
                                7AFBD36E21E546E3005DBACB /* PersistencyUtils.cpp */,
                                7AFBD36D21E546E3005DBACB /* PersistencyUtils.h */,
                                E1CC1B8E12D7EADF00625838 /* PrintInfo.h */,
                                463FD4811EB94EAD00A2982C /* ProcessTerminationReason.h */,
                                F6A0C13F13281E6E0070430F /* ResourceCachesToClear.h */,
+                               5CB7AFE623C681B000E49CF3 /* ResourceLoadInfo.h */,
                                410482CB1DDD2FB500F006D0 /* RTCNetwork.cpp */,
                                410482CC1DDD2FB500F006D0 /* RTCNetwork.h */,
                                41B28B091F83AD3E00FB52AC /* RTCPacketOptions.cpp */,
                                A55BA80D1BA12BE1007CD33D /* _WKRemoteWebInspectorViewController.mm */,
                                990E1E082384A88B004602DF /* _WKRemoteWebInspectorViewControllerPrivate.h */,
                                5CB7AFDF23C52CBC00E49CF3 /* _WKResourceLoadDelegate.h */,
+                               5CB7AFE323C67D3700E49CF3 /* _WKResourceLoadInfo.h */,
+                               5CB7AFE223C67D3700E49CF3 /* _WKResourceLoadInfo.mm */,
+                               5CB7AFE523C67DF900E49CF3 /* _WKResourceLoadInfoInternal.h */,
                                49FBEFFB239ADB1800BD032F /* _WKResourceLoadStatisticsFirstParty.h */,
                                49FBEFFC239B011D00BD032F /* _WKResourceLoadStatisticsFirstParty.mm */,
                                49BCA19023A175490028A836 /* _WKResourceLoadStatisticsFirstPartyInternal.h */,
                                7CE4D21D1A4914CA00C7F152 /* APIProcessPoolConfiguration.cpp */,
                                7CE4D21E1A4914CA00C7F152 /* APIProcessPoolConfiguration.h */,
                                5CB7AFDA23C43E6400E49CF3 /* APIResourceLoadClient.h */,
+                               5CB7AFE423C67D6400E49CF3 /* APIResourceLoadInfo.h */,
                                49BCA19123A177660028A836 /* APIResourceLoadStatisticsFirstParty.h */,
                                49BCA19623A18F620028A836 /* APIResourceLoadStatisticsThirdParty.h */,
                                1AFDE65F1954E9B100C48FFA /* APISessionState.cpp */,
                                377216B81A4E6BE000DCA718 /* _WKRenderingProgressEvents.h in Headers */,
                                1F604BAA1889FBB800EE0395 /* _WKRenderingProgressEventsInternal.h in Headers */,
                                5CB7AFE023C52CE500E49CF3 /* _WKResourceLoadDelegate.h in Headers */,
+                               5CB7AFE823C69B6100E49CF3 /* _WKResourceLoadInfo.h in Headers */,
                                49FBF001239B1F8D00BD032F /* _WKResourceLoadStatisticsFirstParty.h in Headers */,
                                49BCA19523A18CFD0028A836 /* _WKResourceLoadStatisticsFirstPartyInternal.h in Headers */,
                                49FBF000239B1F7500BD032F /* _WKResourceLoadStatisticsThirdParty.h in Headers */,
                                A55BA81F1BA25B27007CD33D /* RemoteWebInspectorProxy.h in Headers */,
                                A55BA8251BA25CFB007CD33D /* RemoteWebInspectorProxyMessages.h in Headers */,
                                A55BA8171BA23E12007CD33D /* RemoteWebInspectorUI.h in Headers */,
+                               5CB7AFE723C6820700E49CF3 /* ResourceLoadInfo.h in Headers */,
                                6BE969CD1E54E054008B7483 /* ResourceLoadStatisticsClassifier.h in Headers */,
                                6BE969CB1E54D4CF008B7483 /* ResourceLoadStatisticsClassifierCocoa.h in Headers */,
                                7AFBD36721E51BAB005DBACB /* ResourceLoadStatisticsMemoryStore.h in Headers */,
index 11d4989..126ce22 100644 (file)
@@ -526,9 +526,10 @@ Optional<WebLoaderStrategy::SyncLoadResult> WebLoaderStrategy::tryLoadingSynchro
 
 void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsigned long resourceLoadIdentifier, const ResourceRequest& request, ClientCredentialPolicy clientCredentialPolicy,  const FetchOptions& options, const HTTPHeaderMap& originalRequestHeaders, ResourceError& error, ResourceResponse& response, Vector<char>& data)
 {
-    WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client());
-    WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
-    WebPage* webPage = webFrame ? webFrame->page() : nullptr;
+    auto* webFrameLoaderClient = toWebFrameLoaderClient(frameLoader.client());
+    auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
+    auto* webPage = webFrame ? webFrame->page() : nullptr;
+    auto* page = webPage ? webPage->corePage() : nullptr;
 
     auto webPageProxyID = webPage ? webPage->webPageProxyIdentifier() : WebPageProxyIdentifier { };
     auto pageID = webPage ? webPage->identifier() : PageIdentifier { };
@@ -579,6 +580,8 @@ void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsi
             loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
     }
     loadParameters.originalRequestHeaders = originalRequestHeaders;
+    if (page)
+        loadParameters.pageHasResourceLoadClient = page->hasResourceLoadClient();
 
     data.shrink(0);
 
@@ -591,7 +594,7 @@ void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsi
 
     if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, data), 0)) {
         WEBLOADERSTRATEGY_WITH_FRAMELOADER_RELEASE_LOG_ERROR_IF_ALLOWED("loadResourceSynchronously: failed sending synchronous network process message");
-        if (auto* page = webPage ? webPage->corePage() : nullptr)
+        if (page)
             page->diagnosticLoggingClient().logDiagnosticMessage(WebCore::DiagnosticLoggingKeys::internalErrorKey(), WebCore::DiagnosticLoggingKeys::synchronousMessageFailedKey(), WebCore::ShouldSample::No);
         response = ResourceResponse();
         error = internalError(request.url());
@@ -644,6 +647,8 @@ void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, co
         if (auto* contentSecurityPolicy = document->contentSecurityPolicy())
             loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
     }
+    if (auto* page = document->page())
+        loadParameters.pageHasResourceLoadClient = page->hasResourceLoadClient();
 
 #if ENABLE(CONTENT_EXTENSIONS)
     loadParameters.mainDocumentURL = document->topDocument().url();
index b50a60c..023e6fe 100644 (file)
@@ -1,5 +1,31 @@
 2020-01-10  Alex Christensen  <achristensen@webkit.org>
 
+        Expand _WKResourceLoadDelegate callbacks
+        https://bugs.webkit.org/show_bug.cgi?id=206037
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadDelegate.mm:
+        (-[TestResourceLoadDelegate webView:resourceLoad:didSendRequest:]):
+        (-[TestResourceLoadDelegate webView:resourceLoad:didPerformHTTPRedirection:newRequest:]):
+        (-[TestResourceLoadDelegate webView:resourceLoad:didReceiveChallenge:]):
+        (-[TestResourceLoadDelegate webView:resourceLoad:didReceiveResponse:]):
+        (-[TestResourceLoadDelegate webView:resourceLoad:didCompleteWithError:]):
+        (TEST):
+        (-[TestResourceLoadDelegate webView:willSendRequest:]): Deleted.
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsiteDataStoreCustomPaths.mm:
+        (TEST):
+        * TestWebKitAPI/cocoa/HTTPServer.h:
+        (TestWebKitAPI::HTTPServer::HTTPResponse::HTTPResponse):
+        Add the ability to have non-200 status codes in responses.
+        Also switch the order of parameters to reflect the fact that header fields are sent before the body.
+        * TestWebKitAPI/cocoa/HTTPServer.mm:
+        (TestWebKitAPI::statusText):
+        (TestWebKitAPI::HTTPServer::respondToRequests):
+
+2020-01-10  Alex Christensen  <achristensen@webkit.org>
+
         Add SPI to enable TLS 1.0 and 1.1 in WKWebViews
         https://bugs.webkit.org/show_bug.cgi?id=206046
 
index e7d4cf9..c493039 100644 (file)
 
 #import "config.h"
 
+#import "HTTPServer.h"
 #import "PlatformUtilities.h"
+#import "TCPServer.h"
 #import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/WebKit.h>
 #import <WebKit/_WKResourceLoadDelegate.h>
+#import <WebKit/_WKResourceLoadInfo.h>
 #import <wtf/RetainPtr.h>
 
 @interface TestResourceLoadDelegate : NSObject <_WKResourceLoadDelegate>
 
-@property (nonatomic, copy) void (^willSendRequest)(WKWebView *, NSURLRequest *);
+@property (nonatomic, copy) void (^didSendRequest)(WKWebView *, _WKResourceLoadInfo *, NSURLRequest *);
+@property (nonatomic, copy) void (^didPerformHTTPRedirection)(WKWebView *, _WKResourceLoadInfo *, NSURLResponse *, NSURLRequest *);
+@property (nonatomic, copy) void (^didReceiveChallenge)(WKWebView *, _WKResourceLoadInfo *, NSURLAuthenticationChallenge *);
+@property (nonatomic, copy) void (^didReceiveResponse)(WKWebView *, _WKResourceLoadInfo *, NSURLResponse *);
+@property (nonatomic, copy) void (^didCompleteWithError)(WKWebView *, _WKResourceLoadInfo *, NSError *);
 
 @end
 
 @implementation TestResourceLoadDelegate
 
-- (void)webView:(WKWebView *)webView willSendRequest:(NSURLRequest *)request
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didSendRequest:(NSURLRequest *)request
 {
-    if (_willSendRequest)
-        _willSendRequest(webView, request);
+    if (_didSendRequest)
+        _didSendRequest(webView, resourceLoad, request);
+}
+
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didPerformHTTPRedirection:(NSURLResponse *)response newRequest:(NSURLRequest *)request
+{
+    if (_didPerformHTTPRedirection)
+        _didPerformHTTPRedirection(webView, resourceLoad, response, request);
+}
+
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+    if (_didReceiveChallenge)
+        _didReceiveChallenge(webView, resourceLoad, challenge);
+}
+
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didReceiveResponse:(NSURLResponse *)response
+{
+    if (_didReceiveResponse)
+        _didReceiveResponse(webView, resourceLoad, response);
+}
+
+- (void)webView:(WKWebView *)webView resourceLoad:(_WKResourceLoadInfo *)resourceLoad didCompleteWithError:(NSError *)error
+{
+    if (_didCompleteWithError)
+        _didCompleteWithError(webView, resourceLoad, error);
 }
 
 @end
@@ -62,7 +94,7 @@ TEST(ResourceLoadDelegate, Basic)
     __block RetainPtr<NSURLRequest> requestFromDelegate;
     auto resourceLoadDelegate = adoptNS([TestResourceLoadDelegate new]);
     [webView _setResourceLoadDelegate:resourceLoadDelegate.get()];
-    [resourceLoadDelegate setWillSendRequest:^(WKWebView *, NSURLRequest *request) {
+    [resourceLoadDelegate setDidSendRequest:^(WKWebView *, _WKResourceLoadInfo *, NSURLRequest *request) {
         requestFromDelegate = request;
     }];
 
@@ -72,3 +104,190 @@ TEST(ResourceLoadDelegate, Basic)
     
     EXPECT_WK_STREQ(requestLoaded.get().URL.absoluteString, requestFromDelegate.get().URL.absoluteString);
 }
+
+#if HAVE(NETWORK_FRAMEWORK)
+
+TEST(ResourceLoadDelegate, BeaconAndSyncXHR)
+{
+    TestWebKitAPI::HTTPServer server({
+        { "/", { "hello" } },
+        { "/xhrTarget", { "hi" } },
+        { "/beaconTarget", { "hi" } },
+    });
+
+    auto webView = adoptNS([TestWKWebView new]);
+    [webView synchronouslyLoadRequest:server.request()];
+
+    __block RetainPtr<NSURLRequest> requestFromDelegate;
+    __block bool receivedCallback = false;
+    auto resourceLoadDelegate = adoptNS([TestResourceLoadDelegate new]);
+    [webView _setResourceLoadDelegate:resourceLoadDelegate.get()];
+    [resourceLoadDelegate setDidSendRequest:^(WKWebView *, _WKResourceLoadInfo *, NSURLRequest *request) {
+        requestFromDelegate = request;
+        receivedCallback = true;
+    }];
+
+    [webView evaluateJavaScript:@"navigator.sendBeacon('/beaconTarget')" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedCallback);
+    EXPECT_WK_STREQ("/beaconTarget", requestFromDelegate.get().URL.path);
+
+    receivedCallback = false;
+    [webView evaluateJavaScript:
+        @"var request = new XMLHttpRequest();"
+        "var asynchronous = false;"
+        "request.open('GET', 'xhrTarget', asynchronous);"
+        "request.send();" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedCallback);
+    EXPECT_WK_STREQ("/xhrTarget", requestFromDelegate.get().URL.path);
+}
+
+TEST(ResourceLoadDelegate, Redirect)
+{
+    TestWebKitAPI::HTTPServer server({
+        { "/", { 301, {{ "Location", "/redirectTarget" }} } },
+        { "/redirectTarget", { "hi" } },
+    });
+
+    __block bool done = false;
+    auto resourceLoadDelegate = adoptNS([TestResourceLoadDelegate new]);
+    [resourceLoadDelegate setDidPerformHTTPRedirection:^(WKWebView *, _WKResourceLoadInfo *, NSURLResponse *response, NSURLRequest *request) {
+        EXPECT_WK_STREQ(response.URL.path, "/");
+        EXPECT_WK_STREQ(request.URL.path, "/redirectTarget");
+        done = true;
+    }];
+
+    auto webView = adoptNS([WKWebView new]);
+    [webView _setResourceLoadDelegate:resourceLoadDelegate.get()];
+    [webView loadRequest:server.request()];
+    TestWebKitAPI::Util::run(&done);
+}
+
+TEST(ResourceLoadDelegate, LoadInfo)
+{
+    TestWebKitAPI::HTTPServer server({
+        { "/", { "<iframe src='iframeSrc'></iframe>" } },
+        { "/iframeSrc", { "<script>fetch('fetchTarget')</script>" } },
+        { "/fetchTarget", { "hi" } },
+    });
+
+    enum class Callback {
+        DidSendRequest,
+        DidReceiveResponse,
+        DidCompleteWithError,
+    };
+
+    __block Vector<Callback> callbacks;
+    __block Vector<RetainPtr<WKWebView>> webViews;
+    __block Vector<RetainPtr<_WKResourceLoadInfo>> loadInfos;
+    __block Vector<RetainPtr<id>> otherParameters;
+
+    __block size_t resourceCompletionCount = 0;
+    auto delegate = adoptNS([TestResourceLoadDelegate new]);
+    [delegate setDidSendRequest:^(WKWebView *webView, _WKResourceLoadInfo *loadInfo, NSURLRequest *request) {
+        callbacks.append(Callback::DidSendRequest);
+        webViews.append(webView);
+        loadInfos.append(loadInfo);
+        otherParameters.append(request);
+    }];
+    [delegate setDidReceiveResponse:^(WKWebView *webView, _WKResourceLoadInfo *loadInfo, NSURLResponse *response) {
+        callbacks.append(Callback::DidReceiveResponse);
+        webViews.append(webView);
+        loadInfos.append(loadInfo);
+        otherParameters.append(response);
+    }];
+    [delegate setDidCompleteWithError:^(WKWebView *webView, _WKResourceLoadInfo *loadInfo, NSError *error) {
+        callbacks.append(Callback::DidCompleteWithError);
+        webViews.append(webView);
+        loadInfos.append(loadInfo);
+        otherParameters.append(error);
+        resourceCompletionCount++;
+    }];
+
+    auto webView = adoptNS([WKWebView new]);
+    [webView _setResourceLoadDelegate:delegate.get()];
+    [webView loadRequest:server.request()];
+    while (resourceCompletionCount < 3)
+        TestWebKitAPI::Util::spinRunLoop();
+
+    Vector<Callback> expectedCallbacks {
+        Callback::DidSendRequest,
+        Callback::DidReceiveResponse,
+        Callback::DidCompleteWithError,
+        Callback::DidSendRequest,
+        Callback::DidReceiveResponse,
+        Callback::DidCompleteWithError,
+        Callback::DidSendRequest,
+        Callback::DidReceiveResponse,
+        Callback::DidCompleteWithError
+    };
+    EXPECT_EQ(callbacks, expectedCallbacks);
+
+    EXPECT_EQ(webViews.size(), 9ull);
+    for (auto& view : webViews)
+        EXPECT_EQ(webView.get(), view.get());
+
+    EXPECT_EQ(loadInfos.size(), 9ull);
+    EXPECT_EQ(loadInfos[0].get().resourceLoadID, loadInfos[1].get().resourceLoadID);
+    EXPECT_EQ(loadInfos[0].get().resourceLoadID, loadInfos[2].get().resourceLoadID);
+    EXPECT_NE(loadInfos[0].get().resourceLoadID, loadInfos[3].get().resourceLoadID);
+    EXPECT_EQ(loadInfos[3].get().resourceLoadID, loadInfos[4].get().resourceLoadID);
+    EXPECT_EQ(loadInfos[3].get().resourceLoadID, loadInfos[5].get().resourceLoadID);
+    EXPECT_NE(loadInfos[3].get().resourceLoadID, loadInfos[6].get().resourceLoadID);
+    EXPECT_EQ(loadInfos[6].get().resourceLoadID, loadInfos[7].get().resourceLoadID);
+    EXPECT_EQ(loadInfos[6].get().resourceLoadID, loadInfos[8].get().resourceLoadID);
+    EXPECT_NE(loadInfos[6].get().resourceLoadID, loadInfos[0].get().resourceLoadID);
+
+    EXPECT_EQ(otherParameters.size(), 9ull);
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[0] class]), "NSMutableURLRequest");
+    EXPECT_WK_STREQ([otherParameters[0] URL].path, "/");
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[1] class]), "NSHTTPURLResponse");
+    EXPECT_WK_STREQ([otherParameters[1] URL].path, "/");
+    EXPECT_EQ(otherParameters[2], nil);
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[3] class]), "NSMutableURLRequest");
+    EXPECT_WK_STREQ([otherParameters[3] URL].path, "/iframeSrc");
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[4] class]), "NSHTTPURLResponse");
+    EXPECT_WK_STREQ([otherParameters[4] URL].path, "/iframeSrc");
+    EXPECT_EQ(otherParameters[5], nil);
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[6] class]), "NSMutableURLRequest");
+    EXPECT_WK_STREQ([otherParameters[6] URL].path, "/fetchTarget");
+    EXPECT_WK_STREQ(NSStringFromClass([otherParameters[7] class]), "NSHTTPURLResponse");
+    EXPECT_WK_STREQ([otherParameters[7] URL].path, "/fetchTarget");
+    EXPECT_EQ(otherParameters[8], nil);
+}
+
+#endif // HAVE(NETWORK_FRAMEWORK)
+
+TEST(ResourceLoadDelegate, Challenge)
+{
+    using namespace TestWebKitAPI;
+    TCPServer server(TCPServer::Protocol::HTTPS, [] (SSL* ssl) {
+        EXPECT_TRUE(!!ssl); // Connection should succeed after a server trust challenge.
+        // Send nothing to make the resource load fail.
+    });
+
+    auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
+    [navigationDelegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    }];
+
+    __block bool receivedErrorNotification = false;
+    __block bool receivedChallengeNotificiation = false;
+    auto resourceLoadDelegate = adoptNS([TestResourceLoadDelegate new]);
+    [resourceLoadDelegate setDidReceiveChallenge:^(WKWebView *, _WKResourceLoadInfo *, NSURLAuthenticationChallenge *challenge) {
+        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+        receivedChallengeNotificiation = true;
+    }];
+    [resourceLoadDelegate setDidCompleteWithError:^(WKWebView *, _WKResourceLoadInfo *, NSError *error) {
+        EXPECT_EQ(error.code, kCFURLErrorCannotConnectToHost);
+        EXPECT_WK_STREQ(error.domain, NSURLErrorDomain);
+        receivedErrorNotification = true;
+    }];
+
+    auto webView = adoptNS([WKWebView new]);
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    [webView _setResourceLoadDelegate:resourceLoadDelegate.get()];
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://127.0.0.1:%d/", server.port()]]]];
+    TestWebKitAPI::Util::run(&receivedErrorNotification);
+    EXPECT_TRUE(receivedChallengeNotificiation);
+}
index 0ceada0..2bce1d0 100644 (file)
@@ -1705,7 +1705,7 @@ TEST(ServiceWorkers, ThrottleCrash)
 
     TestWebKitAPI::HTTPServer server({
         { "/", { mainBytes } },
-        { "/sw.js", { scriptBytes, {{ "Content-Type", "application/javascript" }} } },
+        { "/sw.js", { {{ "Content-Type", "application/javascript" }}, scriptBytes } },
     });
 
     auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
index aa3232f..0381d09 100644 (file)
@@ -578,7 +578,7 @@ TEST(WebKit, ApplicationCacheDirectories)
     TestWebKitAPI::HTTPServer server({
         { "/index.html", { "<html manifest='test.appcache'>" } },
         { "/test.appcache", { "CACHE MANIFEST\nindex.html\ntest.mp4\n" } },
-        { "/test.mp4", { "test!", {{ "Content-Type", "video/test" }}}},
+        { "/test.mp4", { {{ "Content-Type", "video/test" }}, "test!" }},
     });
     
     NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"CustomPathsTest"] isDirectory:YES];
index 3db3150..3826d17 100644 (file)
@@ -52,9 +52,13 @@ private:
 struct HTTPServer::HTTPResponse {
     HTTPResponse(String&& body)
         : body(WTFMove(body)) { }
-    HTTPResponse(String&& body, HashMap<String, String>&& headerFields)
-        : body(WTFMove(body))
-        , headerFields(WTFMove(headerFields)) { }
+    HTTPResponse(HashMap<String, String>&& headerFields, String&& body)
+        : headerFields(WTFMove(headerFields))
+        , body(WTFMove(body)) { }
+    HTTPResponse(unsigned statusCode, HashMap<String, String>&& headerFields, String&& body = { })
+        : statusCode(statusCode)
+        , headerFields(WTFMove(headerFields))
+        , body(WTFMove(body)) { }
 
     HTTPResponse(const HTTPResponse&) = default;
     HTTPResponse(HTTPResponse&&) = default;
@@ -62,8 +66,9 @@ struct HTTPServer::HTTPResponse {
     HTTPResponse& operator=(const HTTPResponse&) = default;
     HTTPResponse& operator=(HTTPResponse&&) = default;
     
-    String body;
+    unsigned statusCode { 200 };
     HashMap<String, String> headerFields;
+    String body;
 };
 
 } // namespace TestWebKitAPI
index 4cf4299..46f2f0e 100644 (file)
@@ -52,6 +52,18 @@ HTTPServer::HTTPServer(std::initializer_list<std::pair<String, HTTPResponse>> re
     nw_listener_start(m_listener.get());
 }
 
+static String statusText(unsigned statusCode)
+{
+    switch (statusCode) {
+    case 200:
+        return "OK"_s;
+    case 301:
+        return "Moved Permanently"_s;
+    }
+    ASSERT_NOT_REACHED();
+    return { };
+}
+
 void HTTPServer::respondToRequests(nw_connection_t connection)
 {
     nw_connection_receive(connection, 1, std::numeric_limits<uint32_t>::max(), ^(dispatch_data_t content, nw_content_context_t context, bool complete, nw_error_t error) {
@@ -76,7 +88,11 @@ void HTTPServer::respondToRequests(nw_connection_t connection)
         
         auto response = m_requestResponseMap.get(path);
         StringBuilder responseBuilder;
-        responseBuilder.append("HTTP/1.1 200 OK\r\nContent-Length: ");
+        responseBuilder.append("HTTP/1.1 ");
+        responseBuilder.appendNumber(response.statusCode);
+        responseBuilder.append(' ');
+        responseBuilder.append(statusText(response.statusCode));
+        responseBuilder.append("\r\nContent-Length: ");
         responseBuilder.appendNumber(response.body.length());
         responseBuilder.append("\r\n");
         for (auto& pair : response.headerFields) {