Network Preflights do not show in WebInspector after moving CORS checks to NetworkProcess
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jun 2018 16:46:43 +0000 (16:46 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Jun 2018 16:46:43 +0000 (16:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186312
<rdar://problem/40495434>

Reviewed by Chris Dumez.

Source/WebCore:

Test: http/wpt/fetch/inspect-preflight.html

No change of behavior in regular conditions.
All intermediate requests/responses are now buffered in NetworkProcess if Web inspector shows up.
Add NetworkLoadInformation and NetworkIntermediateLoadInformation for that purpose.

Add a new LoaderStrategy method to grab this information from NetworkProcess synchronously.
Add Internals API for testing the storage by the Network Process and the sending to WebProcess.

* WebCore.xcodeproj/project.pbxproj:
* loader/LoaderStrategy.cpp:
(WebCore::LoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier):
* loader/LoaderStrategy.h:
* platform/network/NetworkLoadInformation.h: Added.
(WebCore::NetworkTransactionInformation::encode const):
(WebCore::NetworkTransactionInformation::decode):
* testing/Internals.cpp:
(WebCore::Internals::setCaptureExtraNetworkLoadMetricsEnabled):
(WebCore::Internals::ongoingLoadDescriptions):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Add buffering of all request/response of a given load, including redirections and preflights.
This buffering is switched on/off by a boolean which is switched on in case Web Inspector is launched.

Buffering is done in NetworkLoadChecker.
We add ways to retrieve preflight information from NetworkCORSPreflightChecker.

Implement LoaderStrategy new methods through sync IPC.

* NetworkProcess/NetworkCORSPreflightChecker.cpp:
(WebKit::NetworkCORSPreflightChecker::NetworkCORSPreflightChecker):
(WebKit::NetworkCORSPreflightChecker::startPreflight):
(WebKit::NetworkCORSPreflightChecker::willPerformHTTPRedirection):
(WebKit::NetworkCORSPreflightChecker::didReceiveResponseNetworkSession):
(WebKit::NetworkCORSPreflightChecker::didCompleteWithError):
(WebKit::NetworkCORSPreflightChecker::takeInformation):
* NetworkProcess/NetworkCORSPreflightChecker.h:
* NetworkProcess/NetworkConnectionToWebProcess.h:
(WebKit::NetworkConnectionToWebProcess::takeNetworkLoadInformationRequest):
(WebKit::NetworkConnectionToWebProcess::takeNetworkLoadIntermediateInformation):
(WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformation):
(WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformationMetrics):
(WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformationResponse): Deleted.
* NetworkProcess/NetworkConnectionToWebProcess.messages.in:
* NetworkProcess/NetworkLoadChecker.cpp:
(WebKit::NetworkLoadChecker::NetworkLoadChecker):
(WebKit::NetworkLoadChecker::check):
(WebKit::NetworkLoadChecker::checkRedirection):
(WebKit::NetworkLoadChecker::checkResponse):
(WebKit::NetworkLoadChecker::checkCORSRequestWithPreflight):
(WebKit::NetworkLoadChecker::storeRedirection):
* NetworkProcess/NetworkLoadChecker.h:
(WebKit::NetworkLoadChecker::takeNetworkLoadInformation):
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):
(WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::PingLoad):
* Scripts/webkit/messages.py:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier):
* WebProcess/Network/WebLoaderStrategy.h:

LayoutTests:

* http/wpt/fetch/inspect-preflight-expected.txt: Added.
* http/wpt/fetch/inspect-preflight.html: Added.
* http/wpt/fetch/resources/preflight.py: Added.
* platform/mac-wk1/TestExpectations:
* platform/win/TestExpectations:

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

25 files changed:
LayoutTests/ChangeLog
LayoutTests/http/wpt/fetch/inspect-preflight-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/fetch/inspect-preflight.html [new file with mode: 0644]
LayoutTests/http/wpt/fetch/resources/preflight.py [new file with mode: 0644]
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/loader/LoaderStrategy.cpp
Source/WebCore/loader/LoaderStrategy.h
Source/WebCore/platform/network/NetworkLoadInformation.h [new file with mode: 0644]
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.cpp
Source/WebKit/NetworkProcess/NetworkCORSPreflightChecker.h
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp
Source/WebKit/NetworkProcess/NetworkLoadChecker.h
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
Source/WebKit/WebProcess/Network/WebLoaderStrategy.h

index c643ed6..3c21b4c 100644 (file)
@@ -1,3 +1,17 @@
+2018-06-19  Youenn Fablet  <youenn@apple.com>
+
+        Network Preflights do not show in WebInspector after moving CORS checks to NetworkProcess
+        https://bugs.webkit.org/show_bug.cgi?id=186312
+        <rdar://problem/40495434>
+
+        Reviewed by Chris Dumez.
+
+        * http/wpt/fetch/inspect-preflight-expected.txt: Added.
+        * http/wpt/fetch/inspect-preflight.html: Added.
+        * http/wpt/fetch/resources/preflight.py: Added.
+        * platform/mac-wk1/TestExpectations:
+        * platform/win/TestExpectations:
+
 2018-06-19  Antoine Quint  <graouts@apple.com>
 
         Layout Test imported/mozilla/css-animations/test_animation-cancel.html is a flaky failure
diff --git a/LayoutTests/http/wpt/fetch/inspect-preflight-expected.txt b/LayoutTests/http/wpt/fetch/inspect-preflight-expected.txt
new file mode 100644 (file)
index 0000000..1331ee4
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Get preflight information 
+
diff --git a/LayoutTests/http/wpt/fetch/inspect-preflight.html b/LayoutTests/http/wpt/fetch/inspect-preflight.html
new file mode 100644 (file)
index 0000000..b9e9720
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Storing network load information</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+<script>
+promise_test(async (test) => {
+    if (!window.internals)
+        return Promise.reject("Internals API required");
+
+    internals.setCaptureExtraNetworkLoadMetricsEnabled(true);
+
+    const host = get_host_info();
+    await fetch(host.HTTP_REMOTE_ORIGIN + "/WebKit/fetch/resources/preflight.py", { headers : [["header", "value"]] });
+
+    let descriptions = internals.ongoingLoadsDescriptions();
+    internals.setCaptureExtraNetworkLoadMetricsEnabled(false);
+
+    let result = JSON.parse(descriptions)[0][0];
+
+    assert_equals(result[0], 1, "type");
+    assert_equals(result[2], "OPTIONS", "method");
+    assert_equals(result[3], 200, "status");
+
+}, "Get preflight information");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/wpt/fetch/resources/preflight.py b/LayoutTests/http/wpt/fetch/resources/preflight.py
new file mode 100644 (file)
index 0000000..d60d1d0
--- /dev/null
@@ -0,0 +1,17 @@
+import time
+
+def main(request, response):
+    headers = [("Content-Type", "text/plain")]
+    headers.append(("Access-Control-Allow-Origin", "*"))
+    headers.append(("Access-Control-Allow-Methods", "GET"))
+    headers.append(("Access-Control-Allow-Headers", "header"))
+
+    if request.method == "OPTIONS":
+        return 200, headers, ""
+
+    for header in headers:
+        response.headers.set(header[0], header[1])
+    response.write_status_headers()
+    response.writer.write_content("START\n")
+    time.sleep(5);
+    response.writer.write_content("END\n")
index decaf8d..1999bbc 100644 (file)
@@ -458,6 +458,7 @@ webkit.org/b/173432 [ Debug ] imported/w3c/web-platform-tests/fetch/nosniff/impo
 
 # Requires WK2 loading support
 http/wpt/fetch/dnt-header-after-redirection.html [ Skip ]
+http/wpt/fetch/inspect-preflight.html [ Skip ]
 
 # requires wk2 speculative tiling
 fast/images/low-memory-decode.html [ Skip ]
index d80ac25..08a6285 100644 (file)
@@ -3721,6 +3721,7 @@ fast/forms/file/entries-api/webkitdirectory-open-panel.html [ Skip ]
 
 # Requires WK2 loading support
 http/wpt/fetch/dnt-header-after-redirection.html [ Skip ]
+http/wpt/fetch/inspect-preflight.html [ Skip ]
 
 # html/syntax web platform tests are failing on Windows.
 webkit.org/b/162415 imported/w3c/web-platform-tests/html/syntax [ Skip ]
index 407eb59..2f58c80 100644 (file)
@@ -1,3 +1,33 @@
+2018-06-19  Youenn Fablet  <youenn@apple.com>
+
+        Network Preflights do not show in WebInspector after moving CORS checks to NetworkProcess
+        https://bugs.webkit.org/show_bug.cgi?id=186312
+        <rdar://problem/40495434>
+
+        Reviewed by Chris Dumez.
+
+        Test: http/wpt/fetch/inspect-preflight.html
+
+        No change of behavior in regular conditions.
+        All intermediate requests/responses are now buffered in NetworkProcess if Web inspector shows up.
+        Add NetworkLoadInformation and NetworkIntermediateLoadInformation for that purpose.
+
+        Add a new LoaderStrategy method to grab this information from NetworkProcess synchronously.
+        Add Internals API for testing the storage by the Network Process and the sending to WebProcess.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * loader/LoaderStrategy.cpp:
+        (WebCore::LoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier):
+        * loader/LoaderStrategy.h:
+        * platform/network/NetworkLoadInformation.h: Added.
+        (WebCore::NetworkTransactionInformation::encode const):
+        (WebCore::NetworkTransactionInformation::decode):
+        * testing/Internals.cpp:
+        (WebCore::Internals::setCaptureExtraNetworkLoadMetricsEnabled):
+        (WebCore::Internals::ongoingLoadDescriptions):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2018-06-19  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Make imported/mozilla/css-transitions/test_animation-cancel.html pass reliably
index e578f64..4566d7c 100644 (file)
                4161E2D51FE48DC500EC2E96 /* FetchLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4147E2B51C89912600A7E715 /* FetchLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4162A451101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A44E101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h */; };
                4162A4581011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */; };
+               416D75A220C651A500D02D2C /* NetworkLoadInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 416D759F20C6441300D02D2C /* NetworkLoadInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                416E0B3A209BC3CB004A95D9 /* FetchIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E0B37209BC3C2004A95D9 /* FetchIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                416E29A6102FA962007FC14E /* WorkerReportingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E29A5102FA962007FC14E /* WorkerReportingProxy.h */; };
                416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B03D8061BB3110D00B764D9 /* ReadableStreamInternalsBuiltins.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4162A44F101145AE00DFF3ED /* DedicatedWorkerGlobalScope.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DedicatedWorkerGlobalScope.idl; sourceTree = "<group>"; };
                4162A4551011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
                4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDedicatedWorkerGlobalScope.h; sourceTree = "<group>"; };
+               416D759F20C6441300D02D2C /* NetworkLoadInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkLoadInformation.h; sourceTree = "<group>"; };
                416E0B37209BC3C2004A95D9 /* FetchIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchIdentifier.h; sourceTree = "<group>"; };
                416E29A5102FA962007FC14E /* WorkerReportingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerReportingProxy.h; sourceTree = "<group>"; };
                4170A2E91D8C0CC000318452 /* JSDOMWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWrapper.cpp; sourceTree = "<group>"; };
                                514C765D0CE923A1007EF3CD /* HTTPParsers.cpp */,
                                514C765E0CE923A1007EF3CD /* HTTPParsers.h */,
                                628D214B12131ED10055DCFC /* NetworkingContext.h */,
+                               416D759F20C6441300D02D2C /* NetworkLoadInformation.h */,
                                8A81BF8411DCFD9000DA2B98 /* NetworkLoadMetrics.h */,
                                1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */,
                                1A7FA6180DDA3B3A0028F8A5 /* NetworkStateNotifier.h */,
                                656D37430ADBA5DE00A4554D /* NetscapePlugInStreamLoader.h in Headers */,
                                A19D934B1AA11B1E00B46C24 /* NetworkExtensionContentFilter.h in Headers */,
                                628D214C12131ED10055DCFC /* NetworkingContext.h in Headers */,
+                               416D75A220C651A500D02D2C /* NetworkLoadInformation.h in Headers */,
                                8A81BF8511DCFD9000DA2B98 /* NetworkLoadMetrics.h in Headers */,
                                59C27F07138D28CF0079B7E2 /* NetworkResourcesData.h in Headers */,
                                1A7FA6190DDA3B3A0028F8A5 /* NetworkStateNotifier.h in Headers */,
index 838642d..8c6361f 100644 (file)
@@ -26,8 +26,7 @@
 #include "config.h"
 #include "LoaderStrategy.h"
 
-#include "NetworkLoadMetrics.h"
-#include "ResourceResponse.h"
+#include "NetworkLoadInformation.h"
 
 namespace WebCore {
 
@@ -43,6 +42,9 @@ NetworkLoadMetrics LoaderStrategy::networkMetricsFromResourceLoadIdentifier(uint
     return { };
 }
 
-} // namespace WebCore
-
+Vector<NetworkTransactionInformation> LoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier(uint64_t /* resourceLoadIdentifier */)
+{
+    return { };
+}
 
+} // namespace WebCore
index f142b57..d4357a0 100644 (file)
@@ -42,6 +42,7 @@ class FrameLoader;
 class HTTPHeaderMap;
 class NetscapePlugInStreamLoader;
 class NetscapePlugInStreamLoaderClient;
+struct NetworkTransactionInformation;
 class NetworkLoadMetrics;
 class ResourceError;
 class ResourceLoader;
@@ -85,8 +86,12 @@ public:
     virtual bool havePerformedSecurityChecks(const ResourceResponse&) const { return false; }
 
     virtual ResourceResponse responseFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier);
+    virtual Vector<NetworkTransactionInformation> intermediateLoadInformationFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier);
     virtual NetworkLoadMetrics networkMetricsFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier);
 
+    // Used for testing only.
+    virtual Vector<uint64_t> ongoingLoads() const { return { }; }
+
 protected:
     virtual ~LoaderStrategy();
 };
diff --git a/Source/WebCore/platform/network/NetworkLoadInformation.h b/Source/WebCore/platform/network/NetworkLoadInformation.h
new file mode 100644 (file)
index 0000000..3c9360d
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 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 "NetworkLoadMetrics.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include <wtf/EnumTraits.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct NetworkTransactionInformation {
+    enum class Type { Redirection, Preflight };
+    Type type;
+    ResourceRequest request;
+    ResourceResponse response;
+    NetworkLoadMetrics metrics;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<NetworkTransactionInformation> decode(Decoder&);
+};
+
+struct NetworkLoadInformation {
+    ResourceRequest request;
+    ResourceResponse response;
+    NetworkLoadMetrics metrics;
+    Vector<NetworkTransactionInformation> transactions;
+};
+
+}
+
+namespace WTF {
+template<> struct EnumTraits<WebCore::NetworkTransactionInformation::Type> {
+    using values = EnumValues<
+        WebCore::NetworkTransactionInformation::Type,
+        WebCore::NetworkTransactionInformation::Type::Redirection,
+        WebCore::NetworkTransactionInformation::Type::Preflight
+    >;
+};
+}
+
+namespace WebCore {
+
+template<class Encoder> inline void NetworkTransactionInformation::encode(Encoder& encoder) const
+{
+    encoder << type;
+    encoder << request;
+    encoder << response;
+    encoder << metrics;
+}
+
+template<class Decoder> inline std::optional<NetworkTransactionInformation> NetworkTransactionInformation::decode(Decoder& decoder)
+{
+    NetworkTransactionInformation information;
+
+    if (!decoder.decode(information.type))
+        return std::nullopt;
+    if (!decoder.decode(information.request))
+        return std::nullopt;
+    if (!decoder.decode(information.response))
+        return std::nullopt;
+    if (!decoder.decode(information.metrics))
+        return std::nullopt;
+
+    return information;
+}
+
+}
index 94fd8e3..13ce8ae 100644 (file)
@@ -98,6 +98,7 @@
 #include "InternalSettings.h"
 #include "JSImageData.h"
 #include "LibWebRTCProvider.h"
+#include "LoaderStrategy.h"
 #include "MallocStatistics.h"
 #include "MediaPlayer.h"
 #include "MediaProducer.h"
 #include "MockLibWebRTCPeerConnection.h"
 #include "MockPageOverlay.h"
 #include "MockPageOverlayClient.h"
+#include "NetworkLoadInformation.h"
 #if USE(CG)
 #include "PDFDocumentImage.h"
 #endif
 #include "PageOverlay.h"
 #include "PathUtilities.h"
 #include "PlatformMediaSessionManager.h"
+#include "PlatformStrategies.h"
 #include "PrintContext.h"
 #include "PseudoElement.h"
 #include "Range.h"
 #include <wtf/MonotonicTime.h>
 #include <wtf/text/StringBuffer.h>
 #include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 #include <wtf/text/StringView.h>
 
 #if ENABLE(INPUT_TYPE_COLOR)
@@ -4560,4 +4564,31 @@ bool Internals::usingAppleInternalSDK() const
 #endif
 }
 
+void Internals::setCaptureExtraNetworkLoadMetricsEnabled(bool value)
+{
+    platformStrategies()->loaderStrategy()->setCaptureExtraNetworkLoadMetricsEnabled(value);
+}
+
+String Internals::ongoingLoadsDescriptions() const
+{
+    StringBuilder builder;
+    builder.append('[');
+    bool isStarting = true;
+    for (auto& identifier : platformStrategies()->loaderStrategy()->ongoingLoads()) {
+        if (isStarting)
+            isStarting = false;
+        else
+            builder.append(',');
+
+        builder.append('[');
+
+        for (auto& info : platformStrategies()->loaderStrategy()->intermediateLoadInformationFromResourceLoadIdentifier(identifier))
+            builder.append(makeString("[", (int)info.type, ",\"", info.request.url().string(), "\",\"", info.request.httpMethod(), "\",", info.response.httpStatusCode(), "]"));
+
+        builder.append(']');
+    }
+    builder.append(']');
+    return builder.toString();
+}
+    
 } // namespace WebCore
index c977ea7..5abbbf0 100644 (file)
@@ -694,6 +694,9 @@ public:
     using PlaybackControlsPurpose = MediaElementSession::PlaybackControlsPurpose;
     HTMLMediaElement* bestMediaElementForShowingPlaybackControlsManager(PlaybackControlsPurpose);
 
+    void setCaptureExtraNetworkLoadMetricsEnabled(bool);
+    String ongoingLoadsDescriptions() const;
+
 private:
     explicit Internals(Document&);
     Document* contextDocument() const;
index 1f359cc..3e0b4cd 100644 (file)
@@ -623,4 +623,7 @@ enum EventThrottlingBehavior {
     [Conditional=VIDEO, MayThrowException] readonly attribute NowPlayingState nowPlayingState;
 
     [Conditional=VIDEO] HTMLMediaElement bestMediaElementForShowingPlaybackControlsManager(PlaybackControlsPurpose purpose);
+
+    DOMString ongoingLoadsDescriptions();
+    void setCaptureExtraNetworkLoadMetricsEnabled(boolean value);
 };
index aadfbc8..bc669e6 100644 (file)
@@ -1,3 +1,54 @@
+2018-06-19  Youenn Fablet  <youenn@apple.com>
+
+        Network Preflights do not show in WebInspector after moving CORS checks to NetworkProcess
+        https://bugs.webkit.org/show_bug.cgi?id=186312
+        <rdar://problem/40495434>
+
+        Reviewed by Chris Dumez.
+
+        Add buffering of all request/response of a given load, including redirections and preflights.
+        This buffering is switched on/off by a boolean which is switched on in case Web Inspector is launched.
+
+        Buffering is done in NetworkLoadChecker.
+        We add ways to retrieve preflight information from NetworkCORSPreflightChecker.
+
+        Implement LoaderStrategy new methods through sync IPC.
+
+        * NetworkProcess/NetworkCORSPreflightChecker.cpp:
+        (WebKit::NetworkCORSPreflightChecker::NetworkCORSPreflightChecker):
+        (WebKit::NetworkCORSPreflightChecker::startPreflight):
+        (WebKit::NetworkCORSPreflightChecker::willPerformHTTPRedirection):
+        (WebKit::NetworkCORSPreflightChecker::didReceiveResponseNetworkSession):
+        (WebKit::NetworkCORSPreflightChecker::didCompleteWithError):
+        (WebKit::NetworkCORSPreflightChecker::takeInformation):
+        * NetworkProcess/NetworkCORSPreflightChecker.h:
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        (WebKit::NetworkConnectionToWebProcess::takeNetworkLoadInformationRequest):
+        (WebKit::NetworkConnectionToWebProcess::takeNetworkLoadIntermediateInformation):
+        (WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformation):
+        (WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformationMetrics):
+        (WebKit::NetworkConnectionToWebProcess::addNetworkLoadInformationResponse): Deleted.
+        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+        * NetworkProcess/NetworkLoadChecker.cpp:
+        (WebKit::NetworkLoadChecker::NetworkLoadChecker):
+        (WebKit::NetworkLoadChecker::check):
+        (WebKit::NetworkLoadChecker::checkRedirection):
+        (WebKit::NetworkLoadChecker::checkResponse):
+        (WebKit::NetworkLoadChecker::checkCORSRequestWithPreflight):
+        (WebKit::NetworkLoadChecker::storeRedirection):
+        * NetworkProcess/NetworkLoadChecker.h:
+        (WebKit::NetworkLoadChecker::takeNetworkLoadInformation):
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::didReceiveResponse):
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+        (WebKit::NetworkResourceLoader::didRetrieveCacheEntry):
+        * NetworkProcess/PingLoad.cpp:
+        (WebKit::PingLoad::PingLoad):
+        * Scripts/webkit/messages.py:
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier):
+        * WebProcess/Network/WebLoaderStrategy.h:
+
 2018-06-19  Brent Fulgham  <bfulgham@apple.com>
 
         MAP_JIT is not present for minimal simulator builds
index 29250ba..6551ff7 100644 (file)
@@ -39,9 +39,10 @@ namespace WebKit {
 
 using namespace WebCore;
 
-NetworkCORSPreflightChecker::NetworkCORSPreflightChecker(Parameters&& parameters, CompletionCallback&& completionCallback)
+NetworkCORSPreflightChecker::NetworkCORSPreflightChecker(Parameters&& parameters, bool shouldCaptureExtraNetworkLoadMetrics, CompletionCallback&& completionCallback)
     : m_parameters(WTFMove(parameters))
     , m_completionCallback(WTFMove(completionCallback))
+    , m_shouldCaptureExtraNetworkLoadMetrics(shouldCaptureExtraNetworkLoadMetrics)
 {
 }
 
@@ -67,6 +68,9 @@ void NetworkCORSPreflightChecker::startPreflight()
     if (!m_parameters.userAgent.isNull())
         loadParameters.request.setHTTPHeaderField(HTTPHeaderName::UserAgent, m_parameters.userAgent);
 
+    if (m_shouldCaptureExtraNetworkLoadMetrics)
+        m_loadInformation = NetworkTransactionInformation { NetworkTransactionInformation::Type::Preflight, loadParameters.request, { }, { } };
+
     if (auto* networkSession = SessionTracker::networkSession(loadParameters.sessionID)) {
         m_task = NetworkDataTask::create(*networkSession, *this, WTFMove(loadParameters));
         m_task->resume();
@@ -76,6 +80,9 @@ void NetworkCORSPreflightChecker::startPreflight()
 
 void NetworkCORSPreflightChecker::willPerformHTTPRedirection(WebCore::ResourceResponse&& response, WebCore::ResourceRequest&&, RedirectCompletionHandler&& completionHandler)
 {
+    if (m_shouldCaptureExtraNetworkLoadMetrics)
+        m_loadInformation.response = WTFMove(response);
+
     RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection");
     completionHandler({ });
     m_completionCallback(ResourceError { errorDomainWebKitInternal, 0, m_parameters.originalRequest.url(), ASCIILiteral("Preflight response is not successful"), ResourceError::Type::AccessControl });
@@ -97,6 +104,10 @@ void NetworkCORSPreflightChecker::didReceiveChallenge(const WebCore::Authenticat
 void NetworkCORSPreflightChecker::didReceiveResponseNetworkSession(WebCore::ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession");
+
+    if (m_shouldCaptureExtraNetworkLoadMetrics)
+        m_loadInformation.response = response;
+
     m_response = WTFMove(response);
     completionHandler(PolicyAction::Use);
 }
@@ -106,8 +117,11 @@ void NetworkCORSPreflightChecker::didReceiveData(Ref<WebCore::SharedBuffer>&&)
     RELEASE_LOG_IF_ALLOWED("didReceiveData");
 }
 
-void NetworkCORSPreflightChecker::didCompleteWithError(const WebCore::ResourceError& preflightError, const WebCore::NetworkLoadMetrics&)
+void NetworkCORSPreflightChecker::didCompleteWithError(const WebCore::ResourceError& preflightError, const WebCore::NetworkLoadMetrics& metrics)
 {
+    if (m_shouldCaptureExtraNetworkLoadMetrics)
+        m_loadInformation.metrics = metrics;
+
     if (!preflightError.isNull()) {
         RELEASE_LOG_IF_ALLOWED("didCompleteWithError");
         auto error = preflightError;
@@ -145,4 +159,10 @@ void NetworkCORSPreflightChecker::cannotShowURL()
     m_completionCallback(ResourceError { errorDomainWebKitInternal, 0, m_parameters.originalRequest.url(), ASCIILiteral("Preflight response was blocked"), ResourceError::Type::AccessControl });
 }
 
+NetworkTransactionInformation NetworkCORSPreflightChecker::takeInformation()
+{
+    ASSERT(m_shouldCaptureExtraNetworkLoadMetrics);
+    return WTFMove(m_loadInformation);
+}
+
 } // Namespace WebKit
index 42e69e6..e66ea6d 100644 (file)
@@ -26,8 +26,7 @@
 #pragma once
 
 #include "NetworkDataTask.h"
-#include <WebCore/ResourceRequest.h>
-#include <WebCore/ResourceResponse.h>
+#include <WebCore/NetworkLoadInformation.h>
 #include <WebCore/StoredCredentialsPolicy.h>
 #include <pal/SessionID.h>
 #include <wtf/CompletionHandler.h>
@@ -52,12 +51,14 @@ public:
     };
     using CompletionCallback = CompletionHandler<void(WebCore::ResourceError&&)>;
 
-    NetworkCORSPreflightChecker(Parameters&&, CompletionCallback&&);
+    NetworkCORSPreflightChecker(Parameters&&, bool shouldCaptureExtraNetworkLoadMetrics, CompletionCallback&&);
     ~NetworkCORSPreflightChecker();
     const WebCore::ResourceRequest& originalRequest() const { return m_parameters.originalRequest; }
 
     void startPreflight();
 
+    WebCore::NetworkTransactionInformation takeInformation();
+
 private:
     void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
     void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&) final;
@@ -72,6 +73,8 @@ private:
     WebCore::ResourceResponse m_response;
     CompletionCallback m_completionCallback;
     RefPtr<NetworkDataTask> m_task;
+    bool m_shouldCaptureExtraNetworkLoadMetrics { false };
+    WebCore::NetworkTransactionInformation m_loadInformation;
 };
 
 } // namespace WebKit
index 15e5b21..efcd45f 100644 (file)
@@ -33,6 +33,7 @@
 #include "NetworkConnectionToWebProcessMessages.h"
 #include "NetworkMDNSRegister.h"
 #include "NetworkRTCProvider.h"
+#include <WebCore/NetworkLoadInformation.h>
 #include <WebCore/ResourceLoadPriority.h>
 #include <wtf/RefCounted.h>
 
@@ -77,33 +78,37 @@ public:
     void cleanupForSuspension(Function<void()>&&);
     void endSuspension();
 
-    // FIXME: We should store all redirected request/responses.
-    struct NetworkLoadInformation {
-        WebCore::ResourceResponse response;
-        WebCore::NetworkLoadMetrics metrics;
-    };
+    void getNetworkLoadInformationRequest(ResourceLoadIdentifier identifier, WebCore::ResourceRequest& request)
+    {
+        request = m_networkLoadInformationByID.get(identifier).request;
+    }
 
-    void takeNetworkLoadInformationResponse(ResourceLoadIdentifier identifier, WebCore::ResourceResponse& response)
+    void getNetworkLoadInformationResponse(ResourceLoadIdentifier identifier, WebCore::ResourceResponse& response)
     {
         response = m_networkLoadInformationByID.get(identifier).response;
     }
 
+    void getNetworkLoadIntermediateInformation(ResourceLoadIdentifier identifier, Vector<WebCore::NetworkTransactionInformation>& information)
+    {
+        information = m_networkLoadInformationByID.get(identifier).transactions;
+    }
+
     void takeNetworkLoadInformationMetrics(ResourceLoadIdentifier identifier, WebCore::NetworkLoadMetrics& metrics)
     {
         metrics = m_networkLoadInformationByID.take(identifier).metrics;
     }
 
-    void addNetworkLoadInformationResponse(ResourceLoadIdentifier identifier, const WebCore::ResourceResponse& response)
+    void addNetworkLoadInformation(ResourceLoadIdentifier identifier, WebCore::NetworkLoadInformation&& information)
     {
         ASSERT(!m_networkLoadInformationByID.contains(identifier));
-        m_networkLoadInformationByID.add(identifier, NetworkLoadInformation { response, { } });
+        m_networkLoadInformationByID.add(identifier, WTFMove(information));
     }
 
     void addNetworkLoadInformationMetrics(ResourceLoadIdentifier identifier, const WebCore::NetworkLoadMetrics& metrics)
     {
         ASSERT(m_networkLoadInformationByID.contains(identifier));
         m_networkLoadInformationByID.ensure(identifier, [] {
-            return NetworkLoadInformation { };
+            return WebCore::NetworkLoadInformation { };
         }).iterator->value.metrics = metrics;
     }
 
@@ -221,7 +226,7 @@ private:
     HashMap<String, RefPtr<WebCore::BlobDataFileReference>> m_blobDataFileReferences;
     Vector<ResourceNetworkActivityTracker> m_networkActivityTrackers;
 
-    HashMap<ResourceLoadIdentifier, NetworkLoadInformation> m_networkLoadInformationByID;
+    HashMap<ResourceLoadIdentifier, WebCore::NetworkLoadInformation> m_networkLoadInformationByID;
 
 
 #if USE(LIBWEBRTC)
index f4ec633..cac8a2f 100644 (file)
@@ -66,6 +66,8 @@ messages -> NetworkConnectionToWebProcess LegacyReceiver {
     RemoveOriginAccessWhitelistEntry(String sourceOrigin, String destinationProtocol, String destinationHost, bool allowDestinationSubdomains);
     ResetOriginAccessWhitelists();
 
-    TakeNetworkLoadInformationResponse(uint64_t resourceLoadIdentifier) -> (WebCore::ResourceResponse response);
+    GetNetworkLoadInformationRequest(uint64_t resourceLoadIdentifier) -> (WebCore::ResourceRequest request);
+    GetNetworkLoadInformationResponse(uint64_t resourceLoadIdentifier) -> (WebCore::ResourceResponse response);
+    GetNetworkLoadIntermediateInformation(uint64_t resourceLoadIdentifier) -> (Vector<WebCore::NetworkTransactionInformation> transactions);
     TakeNetworkLoadInformationMetrics(uint64_t resourceLoadIdentifier) -> (WebCore::NetworkLoadMetrics networkMetrics);
 }
index ed2a3ec..757b985 100644 (file)
@@ -52,7 +52,7 @@ static inline bool isSameOrigin(const URL& url, const SecurityOrigin* origin)
     return url.protocolIsData() || url.protocolIsBlob() || !origin || origin->canRequest(url);
 }
 
-NetworkLoadChecker::NetworkLoadChecker(NetworkConnectionToWebProcess& connection, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier loadIdentifier, FetchOptions&& options, PAL::SessionID sessionID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer)
+NetworkLoadChecker::NetworkLoadChecker(NetworkConnectionToWebProcess& connection, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier loadIdentifier, FetchOptions&& options, PAL::SessionID sessionID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics)
     : m_connection(connection)
     , m_webPageID(webPageID)
     , m_webFrameID(webFrameID)
@@ -64,6 +64,7 @@ NetworkLoadChecker::NetworkLoadChecker(NetworkConnectionToWebProcess& connection
     , m_origin(WTFMove(sourceOrigin))
     , m_preflightPolicy(preflightPolicy)
     , m_referrer(WTFMove(referrer))
+    , m_shouldCaptureExtraNetworkLoadMetrics(shouldCaptureExtraNetworkLoadMetrics)
 {
     m_isSameOriginRequest = isSameOrigin(m_url, m_origin.get());
     switch (options.credentials) {
@@ -85,6 +86,9 @@ void NetworkLoadChecker::check(ResourceRequest&& request, ValidationHandler&& ha
 {
     ASSERT(!isChecking());
 
+    if (m_shouldCaptureExtraNetworkLoadMetrics)
+        m_loadInformation.request = request;
+
     m_firstRequestHeaders = request.httpHeaderFields();
     // FIXME: We should not get this information from the request but directly from some NetworkProcess setting.
     m_dntHeaderValue = m_firstRequestHeaders.get(HTTPHeaderName::DNT);
@@ -333,7 +337,7 @@ void NetworkLoadChecker::checkCORSRequestWithPreflight(ResourceRequest&& request
         m_sessionID,
         m_storedCredentialsPolicy
     };
-    m_corsPreflightChecker = std::make_unique<NetworkCORSPreflightChecker>(WTFMove(parameters), [this, request = WTFMove(request), handler = WTFMove(handler), isRedirected = isRedirected()](auto&& error) mutable {
+    m_corsPreflightChecker = std::make_unique<NetworkCORSPreflightChecker>(WTFMove(parameters), m_shouldCaptureExtraNetworkLoadMetrics, [this, request = WTFMove(request), handler = WTFMove(handler), isRedirected = isRedirected()](auto&& error) mutable {
         RELEASE_LOG_IF_ALLOWED("checkCORSRequestWithPreflight - makeCrossOriginAccessRequestWithPreflight preflight complete, success: %d forRedirect? %d", error.isNull(), isRedirected);
 
         if (!error.isNull()) {
@@ -341,6 +345,9 @@ void NetworkLoadChecker::checkCORSRequestWithPreflight(ResourceRequest&& request
             return;
         }
 
+        if (m_shouldCaptureExtraNetworkLoadMetrics)
+            m_loadInformation.transactions.append(m_corsPreflightChecker->takeInformation());
+
         auto corsPreflightChecker = WTFMove(m_corsPreflightChecker);
         updateRequestForAccessControl(request, *m_origin, m_storedCredentialsPolicy);
         handler(WTFMove(request));
@@ -404,10 +411,17 @@ void NetworkLoadChecker::sendCSPViolationReport(URL&& reportURL, Ref<FormData>&&
         m_connection->connection().send(Messages::WebPage::SendCSPViolationReport { m_webFrameID, WTFMove(reportURL), IPC::FormDataReference { WTFMove(report) } }, m_webPageID);
 }
 
-void NetworkLoadChecker::enqueueSecurityPolicyViolationEvent(WebCore::SecurityPolicyViolationEvent::Init&& eventInit)
+void NetworkLoadChecker::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&& eventInit)
 {
     if (m_webPageID && m_webFrameID)
         m_connection->connection().send(Messages::WebPage::EnqueueSecurityPolicyViolationEvent { m_webFrameID, WTFMove(eventInit) }, m_webPageID);
 }
 
+void NetworkLoadChecker::storeRedirectionIfNeeded(const ResourceRequest& request, const ResourceResponse& response)
+{
+    if (!m_shouldCaptureExtraNetworkLoadMetrics)
+        return;
+    m_loadInformation.transactions.append(NetworkTransactionInformation { NetworkTransactionInformation::Type::Redirection, ResourceRequest { request }, ResourceResponse { response }, { } });
+}
+
 } // namespace WebKit
index e399881..b41910f 100644 (file)
@@ -28,8 +28,8 @@
 #include "NetworkContentRuleListManager.h"
 #include "NetworkResourceLoadParameters.h"
 #include <WebCore/ContentSecurityPolicyClient.h>
+#include <WebCore/NetworkLoadInformation.h>
 #include <WebCore/ResourceError.h>
-#include <WebCore/ResourceResponse.h>
 #include <WebCore/SecurityPolicyViolationEvent.h>
 #include <wtf/CompletionHandler.h>
 #include <wtf/Expected.h>
@@ -46,7 +46,7 @@ class NetworkCORSPreflightChecker;
 
 class NetworkLoadChecker : public WebCore::ContentSecurityPolicyClient, public CanMakeWeakPtr<NetworkLoadChecker> {
 public:
-    NetworkLoadChecker(NetworkConnectionToWebProcess&, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier, WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer);
+    NetworkLoadChecker(NetworkConnectionToWebProcess&, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier, WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics = false);
     ~NetworkLoadChecker();
 
     using RequestOrError = Expected<WebCore::ResourceRequest, WebCore::ResourceError>;
@@ -69,6 +69,9 @@ public:
     const WebCore::URL& url() const { return m_url; }
     WebCore::StoredCredentialsPolicy storedCredentialsPolicy() const { return m_storedCredentialsPolicy; }
 
+    WebCore::NetworkLoadInformation takeNetworkLoadInformation() { return WTFMove(m_loadInformation); }
+    void storeRedirectionIfNeeded(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
 private:
     WebCore::ContentSecurityPolicy* contentSecurityPolicy();
     bool isChecking() const { return !!m_corsPreflightChecker; }
@@ -130,6 +133,8 @@ private:
     WebCore::PreflightPolicy m_preflightPolicy;
     String m_dntHeaderValue;
     String m_referrer;
+    bool m_shouldCaptureExtraNetworkLoadMetrics { false };
+    WebCore::NetworkLoadInformation m_loadInformation;
 };
 
 }
index c5f6751..4d51ba7 100644 (file)
@@ -119,7 +119,7 @@ NetworkResourceLoader::NetworkResourceLoader(NetworkResourceLoadParameters&& par
     }
 
     if (synchronousReply || parameters.shouldRestrictHTTPResponseAccess) {
-        m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(m_connection, m_parameters.webPageID, m_parameters.webFrameID, identifier(), FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer());
+        m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(m_connection, m_parameters.webPageID, m_parameters.webFrameID, identifier(), FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer(), shouldCaptureExtraNetworkLoadMetrics());
         if (m_parameters.cspResponseHeaders)
             m_networkLoadChecker->setCSPResponseHeaders(ContentSecurityPolicyResponseHeaders { m_parameters.cspResponseHeaders.value() });
 #if ENABLE(CONTENT_EXTENSIONS)
@@ -426,8 +426,11 @@ auto NetworkResourceLoader::didReceiveResponse(ResourceResponse&& receivedRespon
 
     m_response = WTFMove(receivedResponse);
 
-    if (shouldCaptureExtraNetworkLoadMetrics())
-        m_connection->addNetworkLoadInformationResponse(identifier(), m_response);
+    if (shouldCaptureExtraNetworkLoadMetrics() && m_networkLoadChecker) {
+        auto information = m_networkLoadChecker->takeNetworkLoadInformation();
+        information.response = m_response;
+        m_connection->addNetworkLoadInformation(identifier(), WTFMove(information));
+    }
 
     // For multipart/x-mixed-replace didReceiveResponseAsync gets called multiple times and buffering would require special handling.
     if (!isSynchronous() && m_response.isMultipart())
@@ -568,7 +571,7 @@ void NetworkResourceLoader::didBlockAuthenticationChallenge()
     send(Messages::WebResourceLoader::DidBlockAuthenticationChallenge());
 }
 
-void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request, WebCore::ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse)
+void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse)
 {
     ++m_redirectCount;
 
@@ -576,6 +579,7 @@ void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request,
         m_cache->storeRedirect(request, redirectResponse, redirectRequest);
 
     if (m_networkLoadChecker) {
+        m_networkLoadChecker->storeRedirectionIfNeeded(request, redirectResponse);
         m_networkLoadChecker->checkRedirection(redirectResponse, WTFMove(redirectRequest), [protectedThis = makeRef(*this), this, storedCredentialsPolicy = m_networkLoadChecker->storedCredentialsPolicy(), request = WTFMove(request), redirectResponse](auto&& result) mutable {
             if (!result.has_value()) {
                 if (result.error().isCancellation())
index 2881f5f..47fab38 100644 (file)
@@ -388,6 +388,7 @@ def headers_for_type(type):
         'WebCore::IncludeSecureCookies': ['<WebCore/CookiesStrategy.h>'],
         'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'],
         'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'],
+        'WebCore::NetworkTransactionInformation': ['<WebCore/NetworkLoadInformation.h>'],
         'WebCore::PasteboardCustomData': ['<WebCore/Pasteboard.h>'],
         'WebCore::PasteboardImage': ['<WebCore/Pasteboard.h>'],
         'WebCore::PasteboardURL': ['<WebCore/Pasteboard.h>'],
index 097b8bb..95998a5 100644 (file)
 #include <WebCore/Frame.h>
 #include <WebCore/FrameLoader.h>
 #include <WebCore/NetscapePlugInStreamLoader.h>
+#include <WebCore/NetworkLoadInformation.h>
 #include <WebCore/PlatformStrategies.h>
 #include <WebCore/ReferrerPolicy.h>
 #include <WebCore/ResourceLoader.h>
-#include <WebCore/ResourceResponse.h>
 #include <WebCore/RuntimeEnabledFeatures.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/Settings.h>
@@ -654,10 +654,17 @@ void WebLoaderStrategy::setCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
 ResourceResponse WebLoaderStrategy::responseFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier)
 {
     ResourceResponse response;
-    WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::TakeNetworkLoadInformationResponse { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::TakeNetworkLoadInformationResponse::Reply { response }, 0, Seconds::infinity(), IPC::SendSyncOption::DoNotProcessIncomingMessagesWhenWaitingForSyncReply);
+    WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::GetNetworkLoadInformationResponse { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::GetNetworkLoadInformationResponse::Reply { response }, 0, Seconds::infinity(), IPC::SendSyncOption::DoNotProcessIncomingMessagesWhenWaitingForSyncReply);
     return response;
 }
 
+Vector<NetworkTransactionInformation> WebLoaderStrategy::intermediateLoadInformationFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier)
+{
+    Vector<NetworkTransactionInformation> information;
+    WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::GetNetworkLoadIntermediateInformation { resourceLoadIdentifier }, Messages::NetworkConnectionToWebProcess::GetNetworkLoadIntermediateInformation::Reply { information }, 0, Seconds::infinity(), IPC::SendSyncOption::DoNotProcessIncomingMessagesWhenWaitingForSyncReply);
+    return information;
+}
+
 NetworkLoadMetrics WebLoaderStrategy::networkMetricsFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier)
 {
     NetworkLoadMetrics networkMetrics;
index ed023fc..0983f42 100644 (file)
@@ -92,11 +92,19 @@ private:
     bool tryLoadingUsingURLSchemeHandler(WebCore::ResourceLoader&);
 
     WebCore::ResourceResponse responseFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) final;
+    Vector<WebCore::NetworkTransactionInformation> intermediateLoadInformationFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) final;
     WebCore::NetworkLoadMetrics networkMetricsFromResourceLoadIdentifier(uint64_t resourceLoadIdentifier) final;
 
     bool shouldPerformSecurityChecks() const final;
     bool havePerformedSecurityChecks(const WebCore::ResourceResponse&) const final;
 
+    Vector<uint64_t> ongoingLoads() const final
+    {
+        return WTF::map(m_webResourceLoaders, [](auto&& keyValue) -> uint64_t {
+            return keyValue.key;
+        });
+    }
+
     HashSet<RefPtr<WebCore::ResourceLoader>> m_internallyFailedResourceLoaders;
     RunLoop::Timer<WebLoaderStrategy> m_internallyFailedLoadTimer;