Web Inspector: Include Beacon and Ping requests in Network tab
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Oct 2017 20:24:10 +0000 (20:24 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Oct 2017 20:24:10 +0000 (20:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177641
<rdar://problem/33086839>

Reviewed by Chris Dumez.

Source/JavaScriptCore:

* inspector/protocol/Page.json:
Include new "Beacon" and "Ping" resource types.

Source/WebCore:

Tests: http/tests/inspector/network/beacon-type.html
       http/tests/inspector/network/ping-type.html

* Modules/beacon/NavigatorBeacon.cpp:
(WebCore::NavigatorBeacon::sendBeacon):
Fix a typo.

* loader/PingLoader.cpp:
(WebCore::PingLoader::startPingLoad):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::load):
Include InspectorInstrumentation hooks for ping network loads.

* loader/LoaderStrategy.h:
* platform/network/PingHandle.h:
Include an optional ResourceResponse in the ping load completion callback.
If available this will be enough for Web Inspector to include details such
as the response statusCode.

* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::willSendRequestOfTypeImpl):
(WebCore::InspectorInstrumentation::continueAfterPingLoaderImpl): Deleted.
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::willSendRequestOfType):
(WebCore::InspectorInstrumentation::continueAfterPingLoader): Deleted.
* inspector/InspectorNetworkAgent.cpp:
(WebCore::resourceTypeForCachedResource):
(WebCore::resourceTypeForLoadType):
(WebCore::InspectorNetworkAgent::willSendRequest):
(WebCore::InspectorNetworkAgent::willSendRequestOfType):
* inspector/InspectorNetworkAgent.h:
Make a general willSendRequestOfType hook when sending a request that does
not go through normal CachedResource loading. The Ping and Beacon requests
go through this process, we may also use this path for Preflight requests.

* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::resourceTypeJson):
(WebCore::InspectorPageAgent::cachedResourceType):
* inspector/InspectorPageAgent.h:
Small refactoring.

Source/WebInspectorUI:

* Localizations/en.lproj/localizedStrings.js:
New strings for Beacon/Ping.

* UserInterface/Images/Beacon.svg: Added.
* UserInterface/Views/ResourceIcons.css:
(.resource-icon.resource-type-ping .icon,):
(body:not(.mac-platform, .windows-platform) .resource-icon.resource-type-ping .icon,):
(body:not(.mac-platform, .windows-platform) .large .resource-icon.resource-type-ping .icon,):
New icon for Beacon/Ping. They share an icon since they are similiar in concept:
a request that is sent and the page doesn't expect a response.

* UserInterface/Controllers/FrameResourceManager.js:
(WI.FrameResourceManager.prototype._addNewResourceToFrameOrTarget):
When a sub-resource and a main-resource have the same URL we were not
distinguishing them. Use the resource type to distinguish them better.

* UserInterface/Models/SourceCode.js:
(WI.SourceCode.prototype._processContent):
Safer handling if the body was base64 encoded but an empty string.

* UserInterface/Models/Resource.js:
(WI.Resource.displayNameForType):
* UserInterface/Models/ResourceCollection.js:
(WI.ResourceCollection.verifierForType):
* UserInterface/Views/NetworkTableContentView.js:
(WI.NetworkTableContentView.shortDisplayNameForResourceType):
* UserInterface/Views/ResourceClusterContentView.js:
(WI.ResourceClusterContentView.prototype.get responseContentView):
New resource types.

* UserInterface/Views/ResourceContentView.js:
(WI.ResourceContentView.prototype.showMessage):
* UserInterface/Views/TextResourceContentView.js:
(WI.TextResourceContentView.prototype._contentDidPopulate):
Nicer display for empty content, which may be common for these requests.

Source/WebKit:

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::loadPing):
(WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::PingLoad):
(WebKit::PingLoad::didFinish):
(WebKit::PingLoad::didReceiveResponseNetworkSession):
* NetworkProcess/PingLoad.h:
* WebProcess/Network/NetworkProcessConnection.cpp:
(WebKit::NetworkProcessConnection::didFinishPingLoad):
* WebProcess/Network/NetworkProcessConnection.h:
* WebProcess/Network/NetworkProcessConnection.messages.in:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::networkProcessCrashed):
(WebKit::WebLoaderStrategy::startPingLoad):
(WebKit::WebLoaderStrategy::didFinishPingLoad):
* WebProcess/Network/WebLoaderStrategy.h:
Pass an optional ResourceResponse back to the ping completion handler.

LayoutTests:

* http/tests/inspector/network/beacon-type-expected.txt: Added.
* http/tests/inspector/network/beacon-type.html: Added.
* http/tests/inspector/network/ping-type-expected.txt: Added.
* http/tests/inspector/network/ping-type.html: Added.
* http/tests/inspector/network/resources/beacon.php: Added.
* http/tests/inspector/network/resources/ping.php: Added.
Test for Beacon and Ping resource loads.

* platform/mac-wk1/TestExpectations:
* platform/mac-wk2/TestExpectations:
* platform/win/TestExpectations:
Skip beacon tests where beacon is not supported.

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

47 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/inspector/network/beacon-type-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/inspector/network/beacon-type.html [new file with mode: 0644]
LayoutTests/http/tests/inspector/network/ping-type-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/inspector/network/ping-type.html [new file with mode: 0644]
LayoutTests/http/tests/inspector/network/resources/beacon.php [new file with mode: 0644]
LayoutTests/http/tests/inspector/network/resources/ping.php [new file with mode: 0644]
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Page.json
Source/WebCore/ChangeLog
Source/WebCore/Modules/beacon/NavigatorBeacon.cpp
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorNetworkAgent.cpp
Source/WebCore/inspector/InspectorNetworkAgent.h
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/loader/LoaderStrategy.h
Source/WebCore/loader/PingLoader.cpp
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/platform/network/PingHandle.h
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js
Source/WebInspectorUI/UserInterface/Images/Beacon.svg [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Models/Resource.js
Source/WebInspectorUI/UserInterface/Models/ResourceCollection.js
Source/WebInspectorUI/UserInterface/Models/SourceCode.js
Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css
Source/WebInspectorUI/UserInterface/Views/TextResourceContentView.js
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
Source/WebKit/NetworkProcess/PingLoad.cpp
Source/WebKit/NetworkProcess/PingLoad.h
Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
Source/WebKit/WebProcess/Network/NetworkProcessConnection.h
Source/WebKit/WebProcess/Network/NetworkProcessConnection.messages.in
Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
Source/WebKit/WebProcess/Network/WebLoaderStrategy.h

index 00aa995..34f52e6 100644 (file)
@@ -1,3 +1,24 @@
+2017-10-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Include Beacon and Ping requests in Network tab
+        https://bugs.webkit.org/show_bug.cgi?id=177641
+        <rdar://problem/33086839>
+
+        Reviewed by Chris Dumez.
+
+        * http/tests/inspector/network/beacon-type-expected.txt: Added.
+        * http/tests/inspector/network/beacon-type.html: Added.
+        * http/tests/inspector/network/ping-type-expected.txt: Added.
+        * http/tests/inspector/network/ping-type.html: Added.
+        * http/tests/inspector/network/resources/beacon.php: Added.
+        * http/tests/inspector/network/resources/ping.php: Added.
+        Test for Beacon and Ping resource loads.
+
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+        * platform/win/TestExpectations:
+        Skip beacon tests where beacon is not supported.
+
 2017-10-02  Jiewen Tan  <jiewen_tan@apple.com>
 
         Mark imported/w3c/web-platform-tests/WebCryptoAPI/generateKey/successes_RSA-PSS.worker.html as slow
diff --git a/LayoutTests/http/tests/inspector/network/beacon-type-expected.txt b/LayoutTests/http/tests/inspector/network/beacon-type-expected.txt
new file mode 100644 (file)
index 0000000..aaa879c
--- /dev/null
@@ -0,0 +1,22 @@
+Tests for Resource.Type.Beacon.
+
+
+== Running test suite: Resource.Type.Beacon
+-- Running test case: Resource.Type.Beacon.204
+PASS: Resource should be Beacon type.
+PASS: Resource should be a POST request.
+PASS: Resource should have a 204 response.
+PASS: Resource should not have request data.
+
+-- Running test case: Resource.Type.Beacon.404
+PASS: Resource should be Beacon type.
+PASS: Resource should be a POST request.
+PASS: Resource should have a 404 response.
+PASS: Resource should not have request data.
+
+-- Running test case: Resource.Type.Beacon.WithData
+PASS: Resource should be Beacon type.
+PASS: Resource should be a POST request.
+PASS: Resource should have a 200 response.
+PASS: Resource should have 'SENDING-DATA' request data.
+
diff --git a/LayoutTests/http/tests/inspector/network/beacon-type.html b/LayoutTests/http/tests/inspector/network/beacon-type.html
new file mode 100644 (file)
index 0000000..e13b03e
--- /dev/null
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../resources/inspector-test.js"></script>
+<script>
+function triggerBeaconWith204Response() {
+    navigator.sendBeacon("resources/beacon.php?status=204");
+}
+
+function triggerBeaconWith404Response() {
+    navigator.sendBeacon("resources/beacon.php?status=404");
+}
+
+function triggerBeaconWithData() {
+    navigator.sendBeacon("resources/beacon.php", "SENDING-DATA");
+}
+
+// ----
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Resource.Type.Beacon");
+
+    function addTestCase({name, description, expression, resourceHandler}) {
+        suite.addTestCase({
+            name, description,
+            test(resolve, reject) {
+                let resource = null;
+                InspectorTest.evaluateInPage(expression);
+                WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
+                    .then((event) => {
+                        resource = event.data.resource;
+                        alwaysTest(resource);
+                        return Promise.race([
+                            resource.awaitEvent(WI.Resource.Event.LoadingDidFinish),
+                            resource.awaitEvent(WI.Resource.Event.LoadingDidFail),
+                        ]);
+                    })
+                    .then(() => { resourceHandler(resource); })
+                    .then(resolve, reject);
+            }
+        });
+    }
+
+    function alwaysTest(resource) {
+        InspectorTest.expectEqual(resource.type, WI.Resource.Type.Beacon, "Resource should be Beacon type.");
+        InspectorTest.expectEqual(resource.requestMethod, "POST", "Resource should be a POST request.");
+    }
+
+    addTestCase({
+        name: "Resource.Type.Beacon.204",
+        description: "Send a beacon that gets a 204 response.",
+        expression: "triggerBeaconWith204Response()",
+        resourceHandler(resource) {
+            InspectorTest.expectEqual(resource.statusCode, 204, "Resource should have a 204 response.");
+            InspectorTest.expectThat(!resource.requestData, "Resource should not have request data.");
+        }
+    });
+
+    addTestCase({
+        name: "Resource.Type.Beacon.404",
+        description: "Send a beacon that gets a 404 response.",
+        expression: "triggerBeaconWith404Response()",
+        resourceHandler(resource) {
+            InspectorTest.expectEqual(resource.statusCode, 404, "Resource should have a 404 response.");
+            InspectorTest.expectThat(!resource.requestData, "Resource should not have request data.");
+        }
+    });
+
+    addTestCase({
+        name: "Resource.Type.Beacon.WithData",
+        description: "Send a beacon that gets a 404 response.",
+        expression: "triggerBeaconWithData()",
+        resourceHandler(resource) {
+            InspectorTest.expectEqual(resource.statusCode, 200, "Resource should have a 200 response.");
+            InspectorTest.expectEqual(resource.requestData, "SENDING-DATA", "Resource should have 'SENDING-DATA' request data.");
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests for Resource.Type.Beacon.</p>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/inspector/network/ping-type-expected.txt b/LayoutTests/http/tests/inspector/network/ping-type-expected.txt
new file mode 100644 (file)
index 0000000..63756b8
--- /dev/null
@@ -0,0 +1,19 @@
+Tests for Resource.Type.Ping.
+
+Ping 204 Ping 404
+
+== Running test suite: Resource.Type.Ping
+-- Running test case: Resource.Type.Ping.204
+PASS: Resource should be Ping type.
+PASS: Resource should be a POST request.
+PASS: Resource data should be 'PING'.
+Ping-To: http://127.0.0.1:8000/inspector/network/ping-type.html#a204
+PASS: Resource should have a 204 response.
+
+-- Running test case: Resource.Type.Ping.404
+PASS: Resource should be Ping type.
+PASS: Resource should be a POST request.
+PASS: Resource data should be 'PING'.
+Ping-To: http://127.0.0.1:8000/inspector/network/ping-type.html#a404
+PASS: Resource should have a 404 response.
+
diff --git a/LayoutTests/http/tests/inspector/network/ping-type.html b/LayoutTests/http/tests/inspector/network/ping-type.html
new file mode 100644 (file)
index 0000000..e126ac7
--- /dev/null
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../resources/inspector-test.js"></script>
+<script>
+if (window.testRunner && window.internals)
+    internals.settings.setHyperlinkAuditingEnabled(true);
+
+function clickElement(element) {
+    let x = element.offsetLeft + 2;
+    let y = element.offsetTop + 2;
+    let supportsTouchEvents = "TouchEvent" in window;
+    if (supportsTouchEvents && window.testRunner && testRunner.runUIScript)
+        testRunner.runUIScript("(function() { uiController.singleTapAtPoint(" + x + ", " + y + ", function() { /* Do nothing */ }); })();", function() { /* Do nothing */ });
+    else if (window.eventSender) {
+        eventSender.mouseMoveTo(x, y);
+        eventSender.mouseDown();
+        eventSender.mouseUp();
+    }
+}
+
+function triggerPingWith204Response() {
+    clickElement(document.getElementById("a204"));
+}
+
+function triggerPingWith404Response() {
+    clickElement(document.getElementById("a404"));
+}
+
+// ----
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Resource.Type.Ping");
+
+    function addTestCase({name, description, expression, resourceHandler}) {
+        suite.addTestCase({
+            name, description,
+            test(resolve, reject) {
+                let resource = null;
+                InspectorTest.evaluateInPage(expression);
+                WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded)
+                    .then((event) => {
+                        resource = event.data.resource;
+                        alwaysTest(resource);
+                        return Promise.race([
+                            resource.awaitEvent(WI.Resource.Event.LoadingDidFinish),
+                            resource.awaitEvent(WI.Resource.Event.LoadingDidFail),
+                        ]);
+                    })
+                    .then(() => { resourceHandler(resource); })
+                    .then(resolve, reject);
+            }
+        });
+    }
+
+    function alwaysTest(resource) {
+        InspectorTest.expectEqual(resource.type, WI.Resource.Type.Ping, "Resource should be Ping type.");
+        InspectorTest.expectEqual(resource.requestMethod, "POST", "Resource should be a POST request.");
+        InspectorTest.expectEqual(resource.requestData, "PING", "Resource data should be 'PING'.");
+        InspectorTest.log("Ping-To: " + resource.requestHeaders.valueForCaseInsensitiveKey("Ping-To"));
+    }
+
+    addTestCase({
+        name: "Resource.Type.Ping.204",
+        description: "Send a ping that gets a 204 response.",
+        expression: "triggerPingWith204Response()",
+        resourceHandler(resource) {
+            InspectorTest.expectEqual(resource.statusCode, 204, "Resource should have a 204 response.");
+        }
+    });
+
+    addTestCase({
+        name: "Resource.Type.Ping.404",
+        description: "Send a ping that gets a 404 response.",
+        expression: "triggerPingWith404Response()",
+        resourceHandler(resource) {
+            InspectorTest.expectEqual(resource.statusCode, 404, "Resource should have a 404 response.");
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests for Resource.Type.Ping.</p>
+<a id="a204" href="#a204" ping="resources/ping.php?status=204">Ping 204</a>
+<a id="a404" href="#a404" ping="resources/ping.php?status=404">Ping 404</a>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/inspector/network/resources/beacon.php b/LayoutTests/http/tests/inspector/network/resources/beacon.php
new file mode 100644 (file)
index 0000000..047dfba
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+$status = isset($_GET['status']) ? $_GET['status'] : 200;
+
+if ($status == 204) {
+    header("HTTP/1.1 204 No Content");
+    exit;
+}
+
+if ($status == 404) {
+    header("HTTP/1.1 404 Not Found");
+    exit;
+}
+
+echo "Success";
+?>
diff --git a/LayoutTests/http/tests/inspector/network/resources/ping.php b/LayoutTests/http/tests/inspector/network/resources/ping.php
new file mode 100644 (file)
index 0000000..047dfba
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+$status = isset($_GET['status']) ? $_GET['status'] : 200;
+
+if ($status == 204) {
+    header("HTTP/1.1 204 No Content");
+    exit;
+}
+
+if ($status == 404) {
+    header("HTTP/1.1 404 Not Found");
+    exit;
+}
+
+echo "Success";
+?>
index aaddf19..3c4b7b5 100644 (file)
@@ -372,6 +372,7 @@ imported/w3c/web-platform-tests/XMLHttpRequest/event-upload-progress-crossorigin
 
 # Beacon is not supported on WK1.
 http/tests/blink/sendbeacon/ [ Skip ]
+http/tests/inspector/network/beacon-type.html [ Skip ]
 http/wpt/beacon/ [ Skip ]
 imported/blink/fast/beacon/ [ Skip ]
 imported/w3c/web-platform-tests/beacon/ [ Skip ]
index 4da449a..2b9ed96 100644 (file)
@@ -724,6 +724,7 @@ webkit.org/b/172834 [ ElCapitan ] imported/w3c/web-platform-tests/IndexedDB/idbo
 
 # Beacon is not supported on WK2 for the non NETWORK_SESSION code path.
 [ ElCapitan ] http/tests/blink/sendbeacon/ [ Skip ]
+[ ElCapitan ] http/tests/inspector/network/beacon-type.html [ Skip ]
 [ ElCapitan ] http/wpt/beacon/ [ Skip ]
 [ ElCapitan ] imported/blink/fast/beacon/ [ Skip ]
 [ ElCapitan ] imported/w3c/web-platform-tests/beacon/ [ Skip ]
index b9b8858..e732229 100644 (file)
@@ -1430,6 +1430,8 @@ webkit.org/b/168415 [ ElCapitan ] http/wpt/resource-timing/rt-cors.worker.html [
 # Request Header networking data not available without Network Session.
 [ ElCapitan ] http/tests/inspector/network/resource-request-headers.html [ Failure ]
 
+[ ElCapitan ] http/tests/inspector/network/ping-type.html [ Skip ]
+
 # <rdar://problem/30610988>
 [ Sierra+ ] imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-cross-origin.html [ Failure ]
 [ Sierra+ ] imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-worker.html [ Failure ]
index 2b6370d..cb451ca 100644 (file)
@@ -3680,6 +3680,7 @@ webkit.org/b/174079 fast/text/variations/skia-postscript-name.html [ ImageOnlyFa
 
 # Beacon is not supported on WK1.
 http/tests/blink/sendbeacon/ [ Skip ]
+http/tests/inspector/network/beacon-type.html [ Skip ]
 http/wpt/beacon/ [ Skip ]
 imported/blink/fast/beacon/ [ Skip ]
 imported/w3c/web-platform-tests/beacon/ [ Skip ]
index 89aaaba..c9eb48d 100644 (file)
@@ -1,3 +1,14 @@
+2017-10-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Include Beacon and Ping requests in Network tab
+        https://bugs.webkit.org/show_bug.cgi?id=177641
+        <rdar://problem/33086839>
+
+        Reviewed by Chris Dumez.
+
+        * inspector/protocol/Page.json:
+        Include new "Beacon" and "Ping" resource types.
+
 2017-10-02  Caio Lima  <ticaiolima@gmail.com>
 
         ChakraCore/test/Function/apply3.js is resulting wrong result in x86_64
index 2ba7414..3be304f 100644 (file)
@@ -6,7 +6,7 @@
         {
             "id": "ResourceType",
             "type": "string",
-            "enum": ["Document", "Stylesheet", "Image", "Font", "Script", "XHR", "Fetch", "WebSocket", "Other"],
+            "enum": ["Document", "Stylesheet", "Image", "Font", "Script", "XHR", "Fetch", "Ping", "Beacon", "WebSocket", "Other"],
             "description": "Resource type as it was perceived by the rendering engine."
         },
         {
index 122a6a9..7375627 100644 (file)
@@ -1,3 +1,52 @@
+2017-10-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Include Beacon and Ping requests in Network tab
+        https://bugs.webkit.org/show_bug.cgi?id=177641
+        <rdar://problem/33086839>
+
+        Reviewed by Chris Dumez.
+
+        Tests: http/tests/inspector/network/beacon-type.html
+               http/tests/inspector/network/ping-type.html
+
+        * Modules/beacon/NavigatorBeacon.cpp:
+        (WebCore::NavigatorBeacon::sendBeacon):
+        Fix a typo.
+
+        * loader/PingLoader.cpp:
+        (WebCore::PingLoader::startPingLoad):
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::load):
+        Include InspectorInstrumentation hooks for ping network loads.
+
+        * loader/LoaderStrategy.h:
+        * platform/network/PingHandle.h:
+        Include an optional ResourceResponse in the ping load completion callback.
+        If available this will be enough for Web Inspector to include details such
+        as the response statusCode.
+
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::willSendRequestOfTypeImpl):
+        (WebCore::InspectorInstrumentation::continueAfterPingLoaderImpl): Deleted.
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::willSendRequestOfType):
+        (WebCore::InspectorInstrumentation::continueAfterPingLoader): Deleted.
+        * inspector/InspectorNetworkAgent.cpp:
+        (WebCore::resourceTypeForCachedResource):
+        (WebCore::resourceTypeForLoadType):
+        (WebCore::InspectorNetworkAgent::willSendRequest):
+        (WebCore::InspectorNetworkAgent::willSendRequestOfType):
+        * inspector/InspectorNetworkAgent.h:
+        Make a general willSendRequestOfType hook when sending a request that does
+        not go through normal CachedResource loading. The Ping and Beacon requests
+        go through this process, we may also use this path for Preflight requests.
+
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::resourceTypeJson):
+        (WebCore::InspectorPageAgent::cachedResourceType):
+        * inspector/InspectorPageAgent.h:
+        Small refactoring.
+
 2017-10-02  Zalan Bujtas  <zalan@apple.com>
 
         SelectionRangeData should not hold raw RenderObject pointers
index 13732ed..a984d1b 100644 (file)
@@ -103,7 +103,7 @@ ExceptionOr<bool> NavigatorBeacon::sendBeacon(Document& document, const String&
     URL parsedUrl = document.completeURL(url);
 
     // Set parsedUrl to the result of the URL parser steps with url and base. If the algorithm returns an error, or if
-    // parsedUrl's scheme is not "http" or "https", throw a " TypeError" exception and terminate these steps.
+    // parsedUrl's scheme is not "http" or "https", throw a "TypeError" exception and terminate these steps.
     if (!parsedUrl.isValid())
         return Exception { TypeError, ASCIILiteral("This URL is invalid") };
     if (!parsedUrl.protocolIsInHTTPFamily())
index f437c03..c7d5818 100644 (file)
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "InspectorInstrumentation.h"
 
+#include "CachedResource.h"
 #include "DOMWindow.h"
 #include "DOMWrapperWorld.h"
 #include "Database.h"
@@ -560,9 +561,13 @@ void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrume
         networkAgent->willSendRequest(identifier, *loader, request, redirectResponse);
 }
 
-void InspectorInstrumentation::continueAfterPingLoaderImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response)
+void InspectorInstrumentation::willSendRequestOfTypeImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, LoadType loadType)
 {
-    willSendRequestImpl(instrumentingAgents, identifier, loader, request, response);
+    if (!loader)
+        return;
+
+    if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
+        networkAgent->willSendRequestOfType(identifier, *loader, request, loadType);
 }
 
 void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader* loader, CachedResource* cachedResource)
index 250fa84..633b5d0 100644 (file)
@@ -170,7 +170,6 @@ public:
 
     static void applyEmulatedMedia(Frame&, String&);
     static void willSendRequest(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
-    static void continueAfterPingLoader(Frame&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&);
     static void didLoadResourceFromMemoryCache(Page&, DocumentLoader*, CachedResource*);
     static void didReceiveResourceResponse(Frame&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
     static void didReceiveThreadableLoaderResponse(DocumentThreadableLoader&, unsigned long identifier);
@@ -181,6 +180,12 @@ public:
     static void continueWithPolicyDownload(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&);
     static void continueWithPolicyIgnore(Frame&, unsigned long identifier, DocumentLoader&, const ResourceResponse&);
 
+    // Some network requests do not go through the normal network loading path.
+    // These network requests have to issue their own willSendRequest / didReceiveResponse / didFinishLoading / didFailLoading
+    // instrumentation calls. Some of these loads are for resources that lack a CachedResource::Type.
+    enum class LoadType { Ping, Beacon };
+    static void willSendRequestOfType(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, LoadType);
+
     static void didFinishXHRLoading(ScriptExecutionContext*, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber);
     static void willLoadXHRSynchronously(ScriptExecutionContext*);
     static void didLoadXHRSynchronously(ScriptExecutionContext*);
@@ -342,7 +347,7 @@ private:
 
     static void applyEmulatedMediaImpl(InstrumentingAgents&, String&);
     static void willSendRequestImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
-    static void continueAfterPingLoaderImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&);
+    static void willSendRequestOfTypeImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, ResourceRequest&, LoadType);
     static void markResourceAsCachedImpl(InstrumentingAgents&, unsigned long identifier);
     static void didLoadResourceFromMemoryCacheImpl(InstrumentingAgents&, DocumentLoader*, CachedResource*);
     static void didReceiveResourceResponseImpl(InstrumentingAgents&, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
@@ -890,10 +895,10 @@ inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned lon
         willSendRequestImpl(*instrumentingAgents, identifier, loader, request, redirectResponse);
 }
 
-inline void InspectorInstrumentation::continueAfterPingLoader(Frame& frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response)
+inline void InspectorInstrumentation::willSendRequestOfType(Frame* frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, LoadType loadType)
 {
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
-        InspectorInstrumentation::continueAfterPingLoaderImpl(*instrumentingAgents, identifier, loader, request, response);
+        willSendRequestOfTypeImpl(*instrumentingAgents, identifier, loader, request, loadType);
 }
 
 inline void InspectorInstrumentation::didLoadResourceFromMemoryCache(Page& page, DocumentLoader* loader, CachedResource* resource)
index a383897..72fa1ee 100644 (file)
@@ -43,7 +43,6 @@
 #include "FrameLoader.h"
 #include "HTTPHeaderMap.h"
 #include "HTTPHeaderNames.h"
-#include "InspectorPageAgent.h"
 #include "InspectorTimelineAgent.h"
 #include "InstrumentingAgents.h"
 #include "JSMainThreadExecState.h"
@@ -181,7 +180,7 @@ void InspectorNetworkAgent::willDestroyFrontendAndBackend(Inspector::DisconnectR
 static Ref<InspectorObject> buildObjectForHeaders(const HTTPHeaderMap& headers)
 {
     Ref<InspectorObject> headersObject = InspectorObject::create();
-    
+
     for (const auto& header : headers)
         headersObject->setString(header.key, header.value);
     return headersObject;
@@ -336,7 +335,7 @@ double InspectorNetworkAgent::timestamp()
     return m_environment.executionStopwatch()->elapsedTime();
 }
 
-void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
+void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType type)
 {
     if (request.hiddenFromInspector()) {
         m_hiddenRequestIdentifiers.add(identifier);
@@ -346,8 +345,6 @@ void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLo
     String requestId = IdentifiersFactory::requestId(identifier);
     m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(&loader));
 
-    CachedResource* cachedResource = InspectorPageAgent::cachedResource(loader.frame(), request.url());
-    InspectorPageAgent::ResourceType type = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : m_resourcesData->resourceType(requestId);
     if (type == InspectorPageAgent::OtherResource) {
         if (m_loadingXHRSynchronously)
             type = InspectorPageAgent::XHRResource;
@@ -368,12 +365,43 @@ void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLo
     for (auto& entry : m_extraRequestHeaders)
         request.setHTTPHeaderField(entry.key, entry.value);
 
-    Inspector::Protocol::Page::ResourceType resourceType = InspectorPageAgent::resourceTypeJson(type);
+    Inspector::Protocol::Page::ResourceType protocolResourceType = InspectorPageAgent::resourceTypeJson(type);
 
     RefPtr<Inspector::Protocol::Network::Initiator> initiatorObject = buildInitiatorObject(loader.frame() ? loader.frame()->document() : nullptr);
     String targetId = request.initiatorIdentifier();
 
-    m_frontendDispatcher->requestWillBeSent(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), loader.url().string(), buildObjectForResourceRequest(request), timestamp(), initiatorObject, buildObjectForResourceResponse(redirectResponse, nullptr), type != InspectorPageAgent::OtherResource ? &resourceType : nullptr, targetId.isEmpty() ? nullptr : &targetId);
+    m_frontendDispatcher->requestWillBeSent(requestId, m_pageAgent->frameId(loader.frame()), m_pageAgent->loaderId(&loader), loader.url().string(), buildObjectForResourceRequest(request), timestamp(), initiatorObject, buildObjectForResourceResponse(redirectResponse, nullptr), type != InspectorPageAgent::OtherResource ? &protocolResourceType : nullptr, targetId.isEmpty() ? nullptr : &targetId);
+}
+
+static InspectorPageAgent::ResourceType resourceTypeForCachedResource(CachedResource* resource)
+{
+    if (resource)
+        return InspectorPageAgent::inspectorResourceType(*resource);
+    return InspectorPageAgent::OtherResource;
+}
+
+static InspectorPageAgent::ResourceType resourceTypeForLoadType(InspectorInstrumentation::LoadType loadType)
+{
+    switch (loadType) {
+    case InspectorInstrumentation::LoadType::Ping:
+        return InspectorPageAgent::PingResource;
+    case InspectorInstrumentation::LoadType::Beacon:
+        return InspectorPageAgent::BeaconResource;
+    }
+
+    ASSERT_NOT_REACHED();
+    return InspectorPageAgent::OtherResource;
+}
+
+void InspectorNetworkAgent::willSendRequest(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+    auto* cachedResource = InspectorPageAgent::cachedResource(loader.frame(), request.url());
+    willSendRequest(identifier, loader, request, redirectResponse, resourceTypeForCachedResource(cachedResource));
+}
+
+void InspectorNetworkAgent::willSendRequestOfType(unsigned long identifier, DocumentLoader& loader, ResourceRequest& request, InspectorInstrumentation::LoadType loadType)
+{
+    willSendRequest(identifier, loader, request, ResourceResponse(), resourceTypeForLoadType(loadType));
 }
 
 void InspectorNetworkAgent::didReceiveResponse(unsigned long identifier, DocumentLoader& loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
@@ -400,7 +428,7 @@ void InspectorNetworkAgent::didReceiveResponse(unsigned long identifier, Documen
     }
 
     InspectorPageAgent::ResourceType type = m_resourcesData->resourceType(requestId);
-    InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::cachedResourceType(*cachedResource) : type;
+    InspectorPageAgent::ResourceType newType = cachedResource ? InspectorPageAgent::inspectorResourceType(*cachedResource) : type;
 
     // FIXME: XHRResource is returned for CachedResource::RawResource, it should be OtherResource unless it truly is an XHR.
     // RawResource is used for loading worker scripts, and those should stay as ScriptResource and not change to XHRResource.
index fd64892..a785f37 100644 (file)
@@ -31,6 +31,8 @@
 
 #pragma once
 
+#include "InspectorInstrumentation.h"
+#include "InspectorPageAgent.h"
 #include "InspectorWebAgentBase.h"
 #include <inspector/InspectorBackendDispatchers.h>
 #include <inspector/InspectorFrontendDispatchers.h>
@@ -49,7 +51,6 @@ class CachedResource;
 class Document;
 class DocumentLoader;
 class DocumentThreadableLoader;
-class InspectorPageAgent;
 class NetworkLoadMetrics;
 class NetworkResourcesData;
 class ResourceError;
@@ -76,6 +77,7 @@ public:
     void willRecalculateStyle();
     void didRecalculateStyle();
     void willSendRequest(unsigned long identifier, DocumentLoader&, ResourceRequest&, const ResourceResponse& redirectResponse);
+    void willSendRequestOfType(unsigned long identifier, DocumentLoader&, ResourceRequest&, InspectorInstrumentation::LoadType);
     void didReceiveResponse(unsigned long identifier, DocumentLoader&, const ResourceResponse&, ResourceLoader*);
     void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
     void didFinishLoading(unsigned long identifier, DocumentLoader&, const NetworkLoadMetrics&, ResourceLoader*);
@@ -115,6 +117,8 @@ public:
 private:
     void enable();
 
+    void willSendRequest(unsigned long identifier, DocumentLoader&, ResourceRequest&, const ResourceResponse& redirectResponse, InspectorPageAgent::ResourceType);
+
     WebSocket* webSocketForRequestId(const String& requestId);
 
     Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics&, ResourceLoader&);
index f46d6bf..78ff79f 100644 (file)
@@ -101,7 +101,7 @@ static bool hasTextContent(CachedResource* cachedResource)
     // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text
     // We should not assume XHR / Fetch have text content.
 
-    InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource);
+    InspectorPageAgent::ResourceType type = InspectorPageAgent::inspectorResourceType(*cachedResource);
     return type == InspectorPageAgent::DocumentResource
         || type == InspectorPageAgent::StylesheetResource
         || type == InspectorPageAgent::ScriptResource
@@ -263,6 +263,10 @@ Inspector::Protocol::Page::ResourceType InspectorPageAgent::resourceTypeJson(Ins
         return Inspector::Protocol::Page::ResourceType::XHR;
     case FetchResource:
         return Inspector::Protocol::Page::ResourceType::Fetch;
+    case PingResource:
+        return Inspector::Protocol::Page::ResourceType::Ping;
+    case BeaconResource:
+        return Inspector::Protocol::Page::ResourceType::Beacon;
     case WebSocketResource:
         return Inspector::Protocol::Page::ResourceType::WebSocket;
     case OtherResource:
@@ -271,9 +275,9 @@ Inspector::Protocol::Page::ResourceType InspectorPageAgent::resourceTypeJson(Ins
     return Inspector::Protocol::Page::ResourceType::Other;
 }
 
-InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const CachedResource& cachedResource)
+InspectorPageAgent::ResourceType InspectorPageAgent::inspectorResourceType(CachedResource::Type type)
 {
-    switch (cachedResource.type()) {
+    switch (type) {
     case CachedResource::ImageResource:
         return InspectorPageAgent::ImageResource;
 #if ENABLE(SVG_FONTS)
@@ -290,9 +294,19 @@ InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Ca
         return InspectorPageAgent::ScriptResource;
     case CachedResource::MainResource:
         return InspectorPageAgent::DocumentResource;
+    case CachedResource::Beacon:
+        return InspectorPageAgent::BeaconResource;
     case CachedResource::MediaResource:
     case CachedResource::Icon:
-    case CachedResource::RawResource: {
+    case CachedResource::RawResource:
+    default:
+        return InspectorPageAgent::OtherResource;
+    }
+}
+
+InspectorPageAgent::ResourceType InspectorPageAgent::inspectorResourceType(const CachedResource& cachedResource)
+{
+    if (cachedResource.type() == CachedResource::RawResource) {
         switch (cachedResource.resourceRequest().requester()) {
         case ResourceRequest::Requester::Fetch:
             return InspectorPageAgent::FetchResource;
@@ -302,15 +316,13 @@ InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Ca
             return InspectorPageAgent::XHRResource;
         }
     }
-    default:
-        break;
-    }
-    return InspectorPageAgent::OtherResource;
+
+    return inspectorResourceType(cachedResource.type());
 }
 
 Inspector::Protocol::Page::ResourceType InspectorPageAgent::cachedResourceTypeJson(const CachedResource& cachedResource)
 {
-    return resourceTypeJson(cachedResourceType(cachedResource));
+    return resourceTypeJson(inspectorResourceType(cachedResource));
 }
 
 RefPtr<TextResourceDecoder> InspectorPageAgent::createTextDecoder(const String& mimeType, const String& textEncodingName)
index 0c3e56c..073d7c5 100644 (file)
@@ -31,6 +31,7 @@
 
 #pragma once
 
+#include "CachedResource.h"
 #include "InspectorWebAgentBase.h"
 #include "LayoutRect.h"
 #include <inspector/InspectorBackendDispatchers.h>
@@ -45,7 +46,6 @@ class InspectorObject;
 
 namespace WebCore {
 
-class CachedResource;
 class DocumentLoader;
 class Frame;
 class InspectorClient;
@@ -73,6 +73,8 @@ public:
         ScriptResource,
         XHRResource,
         FetchResource,
+        PingResource,
+        BeaconResource,
         WebSocketResource,
         OtherResource,
     };
@@ -84,7 +86,8 @@ public:
 
     static CachedResource* cachedResource(Frame*, const URL&);
     static Inspector::Protocol::Page::ResourceType resourceTypeJson(ResourceType);
-    static ResourceType cachedResourceType(const CachedResource&);
+    static ResourceType inspectorResourceType(CachedResource::Type);
+    static ResourceType inspectorResourceType(const CachedResource&);
     static Inspector::Protocol::Page::ResourceType cachedResourceTypeJson(const CachedResource&);
     static RefPtr<TextResourceDecoder> createTextDecoder(const String& mimeType, const String& textEncodingName);
 
index b57cf95..1e06469 100644 (file)
@@ -65,7 +65,7 @@ public:
     virtual void suspendPendingRequests() = 0;
     virtual void resumePendingRequests() = 0;
 
-    using PingLoadCompletionHandler = WTF::Function<void(const ResourceError&)>;
+    using PingLoadCompletionHandler = WTF::Function<void(const ResourceError&, const ResourceResponse&)>;
     virtual void startPingLoad(Frame&, ResourceRequest&, const HTTPHeaderMap& originalRequestHeaders, const FetchOptions&, PingLoadCompletionHandler&& = { }) = 0;
 
     using PreconnectCompletionHandler = WTF::Function<void(const ResourceError&)>;
index 80d67e3..55ce206 100644 (file)
@@ -41,6 +41,7 @@
 #include "FrameLoaderClient.h"
 #include "InspectorInstrumentation.h"
 #include "LoaderStrategy.h"
+#include "NetworkLoadMetrics.h"
 #include "Page.h"
 #include "PlatformStrategies.h"
 #include "ProgressTracker.h"
@@ -191,7 +192,7 @@ void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, HTTPHeade
 {
     unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
     // FIXME: Why activeDocumentLoader? I would have expected documentLoader().
-    // Itseems like the PingLoader should be associated with the current
+    // It seems like the PingLoader should be associated with the current
     // Document in the Frame, but the activeDocumentLoader will be associated
     // with the provisional DocumentLoader if there is a provisional
     // DocumentLoader.
@@ -200,9 +201,18 @@ void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, HTTPHeade
     options.credentials = shouldUseCredentialStorage ? FetchOptions::Credentials::Include : FetchOptions::Credentials::Omit;
     options.redirect = shouldFollowRedirects == ShouldFollowRedirects::Yes ? FetchOptions::Redirect::Follow : FetchOptions::Redirect::Error;
 
-    InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame.loader().activeDocumentLoader(), request, ResourceResponse());
-
-    platformStrategies()->loaderStrategy()->startPingLoad(frame, request, WTFMove(originalRequestHeaders), options);
+    // FIXME: Move ping loads to normal subresource loading to get normal inspector request instrumentation hooks.
+    InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frame.loader().activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Ping);
+
+    platformStrategies()->loaderStrategy()->startPingLoad(frame, request, WTFMove(originalRequestHeaders), options, [protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
+        if (!response.isNull())
+            InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
+        if (error.isNull()) {
+            NetworkLoadMetrics emptyMetrics;
+            InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
+        } else
+            InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
+    });
 }
 
 }
index 46a317f..d85f9a5 100644 (file)
 #include "FrameLoaderClient.h"
 #include "HTTPHeaderNames.h"
 #include "InspectorInstrumentation.h"
-#include "URL.h"
 #include "LoaderStrategy.h"
 #include "Logging.h"
 #include "MainFrame.h"
 #include "MemoryCache.h"
 #include "PlatformStrategies.h"
+#include "ProgressTracker.h"
 #include "ResourceHandle.h"
 #include "SchemeRegistry.h"
 #include "SecurityOrigin.h"
 #include "SubresourceLoader.h"
+#include "URL.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/MathExtras.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
 #include <wtf/Vector.h>
+#include <wtf/text/CString.h>
 
 #if USE(QUICK_LOOK)
 #include "QuickLook.h"
@@ -270,12 +271,22 @@ void CachedResource::load(CachedResourceLoader& cachedResourceLoader)
         if (shouldUsePingLoad(type())) {
             ASSERT(m_originalRequestHeaders);
             CachedResourceHandle<CachedResource> protectedThis(this);
-            platformStrategies()->loaderStrategy()->startPingLoad(frame, request, *m_originalRequestHeaders, m_options, [this, protectedThis = WTFMove(protectedThis)] (const ResourceError& error) {
-                if (error.isNull())
+
+            // FIXME: Move beacon loads to normal subresource loading to get normal inspector request instrumentation hooks.
+            unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
+            InspectorInstrumentation::willSendRequestOfType(&frame, identifier, frameLoader.activeDocumentLoader(), request, InspectorInstrumentation::LoadType::Beacon);
+
+            platformStrategies()->loaderStrategy()->startPingLoad(frame, request, *m_originalRequestHeaders, m_options, [this, protectedThis = WTFMove(protectedThis), protectedFrame = makeRef(frame), identifier] (const ResourceError& error, const ResourceResponse& response) {
+                if (!response.isNull())
+                    InspectorInstrumentation::didReceiveResourceResponse(protectedFrame, identifier, protectedFrame->loader().activeDocumentLoader(), response, nullptr);
+                if (error.isNull()) {
                     finishLoading(nullptr);
-                else {
+                    NetworkLoadMetrics emptyMetrics;
+                    InspectorInstrumentation::didFinishLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, emptyMetrics, nullptr);
+                } else {
                     setResourceError(error);
                     this->error(LoadError);
+                    InspectorInstrumentation::didFailLoading(protectedFrame.ptr(), protectedFrame->loader().activeDocumentLoader(), identifier, error);
                 }
             });
             return;
index b5de57b..beb9c5a 100644 (file)
@@ -44,7 +44,7 @@ public:
         No,
     };
     
-    PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects, WTF::CompletionHandler<void(const ResourceError&)>&& completionHandler)
+    PingHandle(NetworkingContext* networkingContext, const ResourceRequest& request, bool shouldUseCredentialStorage, UsesAsyncCallbacks useAsyncCallbacks, bool shouldFollowRedirects, WTF::CompletionHandler<void(const ResourceError&, const ResourceResponse&)>&& completionHandler)
         : m_currentRequest(request)
         , m_timeoutTimer(*this, &PingHandle::timeoutTimerFired)
         , m_shouldUseCredentialStorage(shouldUseCredentialStorage)
@@ -73,7 +73,7 @@ private:
         }
         pingLoadComplete(ResourceError { String(), 0, m_currentRequest.url(), ASCIILiteral("Not allowed to follow redirects"), ResourceError::Type::AccessControl });
     }
-    void didReceiveResponse(ResourceHandle*, ResourceResponse&&) final { pingLoadComplete(); }
+    void didReceiveResponse(ResourceHandle*, ResourceResponse&& response) final { pingLoadComplete({ }, response); }
     void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int) final { pingLoadComplete(); }
     void didFinishLoading(ResourceHandle*) final { pingLoadComplete(); }
     void didFail(ResourceHandle*, const ResourceError& error) final { pingLoadComplete(error); }
@@ -81,10 +81,10 @@ private:
     bool usesAsyncCallbacks() final { return m_usesAsyncCallbacks == UsesAsyncCallbacks::Yes; }
     void timeoutTimerFired() { pingLoadComplete(ResourceError { String(), 0, m_currentRequest.url(), ASCIILiteral("Load timed out"), ResourceError::Type::Timeout }); }
 
-    void pingLoadComplete(const ResourceError& error = { })
+    void pingLoadComplete(const ResourceError& error = { }, const ResourceResponse& response = { })
     {
         if (auto completionHandler = std::exchange(m_completionHandler, nullptr))
-            completionHandler(error);
+            completionHandler(error, response);
         delete this;
     }
 
@@ -104,7 +104,7 @@ private:
     bool m_shouldUseCredentialStorage;
     bool m_shouldFollowRedirects;
     UsesAsyncCallbacks m_usesAsyncCallbacks;
-    WTF::CompletionHandler<void(const ResourceError&)> m_completionHandler;
+    WTF::CompletionHandler<void(const ResourceError&, const ResourceResponse&)> m_completionHandler;
 };
 
 } // namespace WebCore
index f5ace88..2634fd7 100644 (file)
@@ -1,3 +1,47 @@
+2017-10-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Include Beacon and Ping requests in Network tab
+        https://bugs.webkit.org/show_bug.cgi?id=177641
+        <rdar://problem/33086839>
+
+        Reviewed by Chris Dumez.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        New strings for Beacon/Ping.
+
+        * UserInterface/Images/Beacon.svg: Added.
+        * UserInterface/Views/ResourceIcons.css:
+        (.resource-icon.resource-type-ping .icon,):
+        (body:not(.mac-platform, .windows-platform) .resource-icon.resource-type-ping .icon,):
+        (body:not(.mac-platform, .windows-platform) .large .resource-icon.resource-type-ping .icon,):
+        New icon for Beacon/Ping. They share an icon since they are similiar in concept:
+        a request that is sent and the page doesn't expect a response.
+
+        * UserInterface/Controllers/FrameResourceManager.js:
+        (WI.FrameResourceManager.prototype._addNewResourceToFrameOrTarget):
+        When a sub-resource and a main-resource have the same URL we were not
+        distinguishing them. Use the resource type to distinguish them better.
+
+        * UserInterface/Models/SourceCode.js:
+        (WI.SourceCode.prototype._processContent):
+        Safer handling if the body was base64 encoded but an empty string.
+
+        * UserInterface/Models/Resource.js:
+        (WI.Resource.displayNameForType):
+        * UserInterface/Models/ResourceCollection.js:
+        (WI.ResourceCollection.verifierForType):
+        * UserInterface/Views/NetworkTableContentView.js:
+        (WI.NetworkTableContentView.shortDisplayNameForResourceType):
+        * UserInterface/Views/ResourceClusterContentView.js:
+        (WI.ResourceClusterContentView.prototype.get responseContentView):
+        New resource types.
+
+        * UserInterface/Views/ResourceContentView.js:
+        (WI.ResourceContentView.prototype.showMessage):
+        * UserInterface/Views/TextResourceContentView.js:
+        (WI.TextResourceContentView.prototype._contentDidPopulate):
+        Nicer display for empty content, which may be common for these requests.
+
 2017-09-29  Nikita Vasilyev  <nvasilyev@apple.com>
 
         Web Inspector: Styles Redesign: support undo/redo of manual edits
index b49ea2f..0577033 100644 (file)
@@ -124,6 +124,8 @@ localizedStrings["Average Time"] = "Average Time";
 localizedStrings["Back (%s)"] = "Back (%s)";
 localizedStrings["Background"] = "Background";
 localizedStrings["Basis"] = "Basis";
+localizedStrings["Beacon"] = "Beacon";
+localizedStrings["Beacons"] = "Beacons";
 localizedStrings["Bezier"] = "Bezier";
 localizedStrings["Binary Frame"] = "Binary Frame";
 localizedStrings["Blend"] = "Blend";
@@ -651,7 +653,9 @@ localizedStrings["Passive"] = "Passive";
 localizedStrings["Path"] = "Path";
 localizedStrings["Pause Reason"] = "Pause Reason";
 localizedStrings["Pause script execution (%s or %s)"] = "Pause script execution (%s or %s)";
+localizedStrings["Ping"] = "Ping";
 localizedStrings["Ping Frame"] = "Ping Frame";
+localizedStrings["Pings"] = "Pings";
 localizedStrings["Play Sound"] = "Play Sound";
 localizedStrings["Polite"] = "Polite";
 localizedStrings["Pong Frame"] = "Pong Frame";
@@ -718,6 +722,7 @@ localizedStrings["Resource"] = "Resource";
 localizedStrings["Resource Size"] = "Resource Size";
 localizedStrings["Resource Type"] = "Resource Type";
 localizedStrings["Resource failed to load."] = "Resource failed to load.";
+localizedStrings["Resource has no content"] = "Resource has no content";
 localizedStrings["Resource was loaded with the “data“ scheme."] = "Resource was loaded with the “data“ scheme.";
 localizedStrings["Resource was served from the cache."] = "Resource was served from the cache.";
 localizedStrings["Resources"] = "Resources";
@@ -981,6 +986,7 @@ localizedStrings["for changes to take effect"] = "for changes to take effect";
 localizedStrings["key"] = "key";
 localizedStrings["line "] = "line ";
 localizedStrings["originally %s"] = "originally %s";
+localizedStrings["ping"] = "ping";
 localizedStrings["popup"] = "popup";
 localizedStrings["popup, toggle"] = "popup, toggle";
 localizedStrings["spaces"] = "spaces";
index 1751c0f..c0f659d 100644 (file)
@@ -502,9 +502,9 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
         let frame = this.frameForIdentifier(frameIdentifier);
         if (frame) {
             // This is a new request for an existing frame, which might be the main resource or a new resource.
-            if (frame.mainResource.url === url && frame.loaderIdentifier === loaderIdentifier)
+            if (type === PageAgent.ResourceType.Document && frame.mainResource.url === url && frame.loaderIdentifier === loaderIdentifier)
                 resource = frame.mainResource;
-            else if (frame.provisionalMainResource && frame.provisionalMainResource.url === url && frame.provisionalLoaderIdentifier === loaderIdentifier)
+            else if (type === PageAgent.ResourceType.Document && frame.provisionalMainResource && frame.provisionalMainResource.url === url && frame.provisionalLoaderIdentifier === loaderIdentifier)
                 resource = frame.provisionalMainResource;
             else {
                 resource = new WI.Resource(url, null, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, initiatorSourceCodeLocation, originalRequestWillBeSentTimestamp);
@@ -674,7 +674,7 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
             // The main resource is included as a resource. We can skip it since we already created
             // a main resource when we created the Frame. The resource payload does not include anything
             // didn't already get from the frame payload.
-            if (resourcePayload.type === "Document" && resourcePayload.url === payload.frame.url)
+            if (resourcePayload.type === PageAgent.ResourceType.Document && resourcePayload.url === payload.frame.url)
                 continue;
 
             var resource = this._createResource(resourcePayload, payload);
diff --git a/Source/WebInspectorUI/UserInterface/Images/Beacon.svg b/Source/WebInspectorUI/UserInterface/Images/Beacon.svg
new file mode 100644 (file)
index 0000000..afa3774
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2017 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+  <circle cx="8" cy="8" r="5.5" stroke="hsla(0, 0%, 40%, 0.65)" fill="white"/>
+  <circle cx="8" cy="8" r="3" stroke="hsla(0, 0%, 40%, 0.9)" fill="none"/>
+  <circle cx="8" cy="8" r="0.5" stroke="hsl(0, 0%, 40%" fill="none"/>
+</svg>
index 566d85f..2fcc4b5 100644 (file)
@@ -140,6 +140,14 @@ WI.Resource = class Resource extends WI.SourceCode
             if (plural)
                 return WI.UIString("Fetches");
             return WI.UIString("Fetch");
+        case WI.Resource.Type.Ping:
+            if (plural)
+                return WI.UIString("Pings");
+            return WI.UIString("Ping");
+        case WI.Resource.Type.Beacon:
+            if (plural)
+                return WI.UIString("Beacons");
+            return WI.UIString("Beacon");
         case WI.Resource.Type.WebSocket:
             if (plural)
                 return WI.UIString("Sockets");
@@ -1008,8 +1016,10 @@ WI.Resource.Type = {
     Script: "resource-type-script",
     XHR: "resource-type-xhr",
     Fetch: "resource-type-fetch",
+    Ping: "resource-type-ping",
+    Beacon: "resource-type-beacon",
     WebSocket: "resource-type-websocket",
-    Other: "resource-type-other"
+    Other: "resource-type-other",
 };
 
 WI.Resource.ResponseSource = {
index cd796b8..3027810 100644 (file)
@@ -53,6 +53,10 @@ WI.ResourceCollection = class ResourceCollection extends WI.Collection
             return WI.ResourceCollection.TypeVerifier.XHR;
         case WI.Resource.Type.Fetch:
             return WI.ResourceCollection.TypeVerifier.Fetch;
+        case WI.Resource.Type.Ping:
+            return WI.ResourceCollection.TypeVerifier.Ping;
+        case WI.Resource.Type.Beacon:
+            return WI.ResourceCollection.TypeVerifier.Beacon;
         case WI.Resource.Type.WebSocket:
             return WI.ResourceCollection.TypeVerifier.WebSocket;
         case WI.Resource.Type.Other:
@@ -200,6 +204,7 @@ WI.ResourceCollection.TypeVerifier = {
     Script: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Script,
     XHR: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.XHR,
     Fetch: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Fetch,
+    Beacon: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Beacon,
     WebSocket: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.WebSocket,
     Other: (object) => WI.Collection.TypeVerifier.Resource(object) && object.type === WI.Resource.Type.Other,
 };
index 0b1d1d7..83371ec 100644 (file)
@@ -197,7 +197,7 @@ WI.SourceCode = class SourceCode extends WI.Object
         var content = parameters.content || parameters.body || parameters.text || parameters.scriptSource;
         var error = parameters.error;
         if (parameters.base64Encoded)
-            content = decodeBase64ToBlob(content, this.mimeType);
+            content = content ? decodeBase64ToBlob(content, this.mimeType) : "";
 
         var revision = this.revisionForRequestedContent;
 
index 65195a0..76c6a73 100644 (file)
@@ -108,6 +108,10 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
         case WI.Resource.Type.XHR:
         case WI.Resource.Type.Fetch:
             return "XHR";
+        case WI.Resource.Type.Ping:
+            return WI.UIString("ping");
+        case WI.Resource.Type.Beacon:
+            return WI.UIString("Beacon");
         case WI.Resource.Type.WebSocket:
         case WI.Resource.Type.Other:
             return WI.UIString("Other");
index e76bca1..f1eafc0 100644 (file)
@@ -71,8 +71,10 @@ WI.ResourceClusterContentView = class ResourceClusterContentView extends WI.Clus
 
         case WI.Resource.Type.XHR:
         case WI.Resource.Type.Fetch:
+        case WI.Resource.Type.Ping:
+        case WI.Resource.Type.Beacon:
             // FIXME: <https://webkit.org/b/165495> Web Inspector: XHR / Fetch for non-text content should not show garbled text
-            // XHR / Fetch content may not always be text.
+            // The response content for these requests may not always be text.
             this._responseContentView = new WI.TextResourceContentView(this._resource);
             break;
 
index dc1b518..536c652 100644 (file)
@@ -86,6 +86,12 @@ WI.ResourceContentView = class ResourceContentView extends WI.ContentView
         this._contentError(WI.UIString("An error occurred trying to load the resource."));
     }
 
+    showMessage(message)
+    {
+        this.element.removeChildren();
+        this.element.appendChild(WI.createMessageTextView(message));
+    }
+
     addIssue(issue)
     {
         // This generically shows only the last issue, subclasses can override for better handling.
index 77338ef..59bc02e 100644 (file)
     content: image-set(url(../Images/WebSocket.png) 1x, url(../Images/WebSocket@2x.png) 2x);
 }
 
+.resource-icon.resource-type-ping .icon,
+.resource-icon.resource-type-beacon .icon {
+    content: url(../Images/Beacon.svg);
+}
+
 .canvas.canvas-2d .icon {
     content: url(../Images/Canvas2D.svg);
 }
 .large .resource-icon.resource-type-websocket .icon {
     content: image-set(url(../Images/WebSocketLarge.png) 1x, url(../Images/WebSocketLarge@2x.png) 2x);
 }
+
+/* FIXME: <https://webkit.org/b/177642> Web Inspector: Add GTK icons for Beacon / Ping requests */
+body:not(.mac-platform, .windows-platform) .resource-icon.resource-type-ping .icon,
+body:not(.mac-platform, .windows-platform) .resource-icon.resource-type-beacon .icon {
+    content: image-set(url(../Images/DocumentGeneric.png) 1x, url(../Images/DocumentGeneric@2x.png) 2x);
+}
+body:not(.mac-platform, .windows-platform) .large .resource-icon.resource-type-ping .icon,
+body:not(.mac-platform, .windows-platform) .large .resource-icon.resource-type-beacon .icon {
+    content: image-set(url(../Images/DocumentGenericLarge.png) 1x, url(../Images/DocumentGenericLarge@2x.png) 2x);
+}
index 4de1f27..1a24930 100644 (file)
@@ -208,6 +208,9 @@ WI.TextResourceContentView = class TextResourceContentView extends WI.ResourceCo
 
         this._codeCoverageButtonNavigationItem.enabled = this._textEditor.canShowCoverageHints();
         this._codeCoverageButtonNavigationItem.activated = WI.enableControlFlowProfilerSetting.value;
+
+        if (!this._textEditor.string)
+            this.showMessage(WI.UIString("Resource has no content"));
     }
 
     _togglePrettyPrint(event)
index 67a6396..734776d 100644 (file)
@@ -1,3 +1,31 @@
+2017-10-02  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Include Beacon and Ping requests in Network tab
+        https://bugs.webkit.org/show_bug.cgi?id=177641
+        <rdar://problem/33086839>
+
+        Reviewed by Chris Dumez.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::loadPing):
+        (WebKit::NetworkConnectionToWebProcess::didFinishPingLoad):
+        * NetworkProcess/NetworkConnectionToWebProcess.h:
+        * NetworkProcess/PingLoad.cpp:
+        (WebKit::PingLoad::PingLoad):
+        (WebKit::PingLoad::didFinish):
+        (WebKit::PingLoad::didReceiveResponseNetworkSession):
+        * NetworkProcess/PingLoad.h:
+        * WebProcess/Network/NetworkProcessConnection.cpp:
+        (WebKit::NetworkProcessConnection::didFinishPingLoad):
+        * WebProcess/Network/NetworkProcessConnection.h:
+        * WebProcess/Network/NetworkProcessConnection.messages.in:
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::networkProcessCrashed):
+        (WebKit::WebLoaderStrategy::startPingLoad):
+        (WebKit::WebLoaderStrategy::didFinishPingLoad):
+        * WebProcess/Network/WebLoaderStrategy.h:
+        Pass an optional ResourceResponse back to the ping completion handler.
+
 2017-10-02  Alex Christensen  <achristensen@webkit.org>
 
         REGRESSION: API tests WebKit.ProcessDidTerminateRequestedByClient and WebKit.ProcessDidTerminateWithReasonCrash are timing out
index 5b11493..ea41f8e 100644 (file)
@@ -240,8 +240,8 @@ void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResource
 
 void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loadParameters, HTTPHeaderMap&& originalRequestHeaders)
 {
-    auto completionHandler = [this, protectedThis = makeRef(*this), identifier = loadParameters.identifier] (const ResourceError& error) {
-        didFinishPingLoad(identifier, error);
+    auto completionHandler = [this, protectedThis = makeRef(*this), identifier = loadParameters.identifier] (const ResourceError& error, const ResourceResponse& response) {
+        didFinishPingLoad(identifier, error, response);
     };
 
 #if USE(NETWORK_SESSION)
@@ -256,12 +256,12 @@ void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loa
 #endif
 }
 
-void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier, const ResourceError& error)
+void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier, const ResourceError& error, const ResourceResponse& response)
 {
     if (!m_connection->isValid())
         return;
 
-    m_connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(pingLoadIdentifier, error), 0);
+    m_connection->send(Messages::NetworkProcessConnection::DidFinishPingLoad(pingLoadIdentifier, error, response), 0);
 }
 
 void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
index 3aed7eb..7891a67 100644 (file)
@@ -65,7 +65,7 @@ public:
     IPC::Connection& connection() { return m_connection.get(); }
 
     void didCleanupResourceLoader(NetworkResourceLoader&);
-    void didFinishPingLoad(uint64_t pingLoadIdentifier, const WebCore::ResourceError&);
+    void didFinishPingLoad(uint64_t pingLoadIdentifier, const WebCore::ResourceError&, const WebCore::ResourceResponse&);
 
     bool captureExtraNetworkLoadMetricsEnabled() const { return m_captureExtraNetworkLoadMetricsEnabled; }
 
index 0510ea4..49e23d9 100644 (file)
@@ -44,7 +44,7 @@ namespace WebKit {
 
 using namespace WebCore;
 
-PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, HTTPHeaderMap&& originalRequestHeaders, WTF::CompletionHandler<void(const ResourceError&)>&& completionHandler)
+PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, HTTPHeaderMap&& originalRequestHeaders, WTF::CompletionHandler<void(const ResourceError&, const ResourceResponse&)>&& completionHandler)
     : m_parameters(WTFMove(parameters))
     , m_originalRequestHeaders(WTFMove(originalRequestHeaders))
     , m_completionHandler(WTFMove(completionHandler))
@@ -77,9 +77,9 @@ PingLoad::~PingLoad()
     }
 }
 
-void PingLoad::didFinish(const ResourceError& error)
+void PingLoad::didFinish(const ResourceError& error, const ResourceResponse& response)
 {
-    m_completionHandler(error);
+    m_completionHandler(error, response);
     delete this;
 }
 
@@ -175,7 +175,7 @@ void PingLoad::didReceiveResponseNetworkSession(ResourceResponse&& response, Res
 {
     RELEASE_LOG_IF_ALLOWED("didReceiveResponseNetworkSession - httpStatusCode: %d", response.httpStatusCode());
     completionHandler(PolicyAction::Ignore);
-    didFinish();
+    didFinish({ }, response);
 }
 
 void PingLoad::didReceiveData(Ref<SharedBuffer>&&)
index c28c014..c39f379 100644 (file)
@@ -31,6 +31,7 @@
 #include "NetworkResourceLoadParameters.h"
 #include <WebCore/ContentExtensionsBackend.h>
 #include <WebCore/ResourceError.h>
+#include <WebCore/ResourceResponse.h>
 #include <wtf/CompletionHandler.h>
 
 namespace WebCore {
@@ -45,7 +46,7 @@ class NetworkCORSPreflightChecker;
 
 class PingLoad final : private NetworkDataTaskClient {
 public:
-    PingLoad(NetworkResourceLoadParameters&&, WebCore::HTTPHeaderMap&& originalRequestHeaders, WTF::CompletionHandler<void(const WebCore::ResourceError&)>&&);
+    PingLoad(NetworkResourceLoadParameters&&, WebCore::HTTPHeaderMap&& originalRequestHeaders, WTF::CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&&);
     
 private:
     ~PingLoad();
@@ -77,11 +78,11 @@ private:
     WebCore::SecurityOrigin& securityOrigin() const;
 
     const WebCore::ResourceRequest& currentRequest() const;
-    void didFinish(const WebCore::ResourceError& = { });
+    void didFinish(const WebCore::ResourceError& = { }, const WebCore::ResourceResponse& response = { });
     
     NetworkResourceLoadParameters m_parameters;
     WebCore::HTTPHeaderMap m_originalRequestHeaders; // Needed for CORS checks.
-    WTF::CompletionHandler<void(const WebCore::ResourceError&)> m_completionHandler;
+    WTF::CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)> m_completionHandler;
     RefPtr<NetworkDataTask> m_task;
     WebCore::Timer m_timeoutTimer;
     std::unique_ptr<NetworkCORSPreflightChecker> m_corsPreflightChecker;
index edc945e..8c615f0 100644 (file)
@@ -136,9 +136,9 @@ void NetworkProcessConnection::didWriteBlobsToTemporaryFiles(uint64_t requestIde
         handler(filenames);
 }
 
-void NetworkProcessConnection::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error)
+void NetworkProcessConnection::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error, ResourceResponse&& response)
 {
-    WebProcess::singleton().webLoaderStrategy().didFinishPingLoad(pingLoadIdentifier, WTFMove(error));
+    WebProcess::singleton().webLoaderStrategy().didFinishPingLoad(pingLoadIdentifier, WTFMove(error), WTFMove(response));
 }
 
 void NetworkProcessConnection::didFinishPreconnection(uint64_t preconnectionIdentifier, ResourceError&& error)
index deea7b0..f2f3f22 100644 (file)
@@ -73,7 +73,7 @@ private:
     void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
 
     void didWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, const Vector<String>& filenames);
-    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&);
+    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&, WebCore::ResourceResponse&&);
     void didFinishPreconnection(uint64_t preconnectionIdentifier, WebCore::ResourceError&&);
 
 #if ENABLE(SHAREABLE_RESOURCE)
index 287363e..86c2d13 100644 (file)
@@ -27,6 +27,6 @@ messages -> NetworkProcessConnection LegacyReceiver {
 #endif
 
     DidWriteBlobsToTemporaryFiles(uint64_t requestIdentifier, Vector<String> filenames)
-    DidFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError error)
+    DidFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError error, WebCore::ResourceResponse response)
     DidFinishPreconnection(uint64_t preconnectionIdentifier, WebCore::ResourceError error)
 }
index 2f15b3d..0923e70 100644 (file)
@@ -355,7 +355,7 @@ void WebLoaderStrategy::networkProcessCrashed()
 
     auto pingLoadCompletionHandlers = WTFMove(m_pingLoadCompletionHandlers);
     for (auto& pingLoadCompletionHandler : pingLoadCompletionHandlers.values())
-        pingLoadCompletionHandler(internalError(URL()));
+        pingLoadCompletionHandler(internalError(URL()), { });
 
     auto preconnectCompletionHandlers = WTFMove(m_preconnectCompletionHandlers);
     for (auto& preconnectCompletionHandler : preconnectCompletionHandlers.values())
@@ -409,7 +409,7 @@ void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, co
     auto* networkingContext = frame.loader().networkingContext();
     if (!networkingContext) {
         if (completionHandler)
-            completionHandler(internalError(request.url()));
+            completionHandler(internalError(request.url()), { });
         return;
     }
 
@@ -421,7 +421,7 @@ void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, co
     auto* document = frame.document();
     if (!document) {
         if (completionHandler)
-            completionHandler(internalError(request.url()));
+            completionHandler(internalError(request.url()), { });
         return;
     }
     
@@ -457,10 +457,10 @@ void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, co
     WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing(WTFMove(loadParameters), originalRequestHeaders), 0);
 }
 
-void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error)
+void WebLoaderStrategy::didFinishPingLoad(uint64_t pingLoadIdentifier, ResourceError&& error, ResourceResponse&& response)
 {
     if (auto completionHandler = m_pingLoadCompletionHandlers.take(pingLoadIdentifier))
-        completionHandler(WTFMove(error));
+        completionHandler(WTFMove(error), WTFMove(response));
 }
 
 void WebLoaderStrategy::preconnectTo(NetworkingContext& context, const WebCore::URL& url, StoredCredentialsPolicy storedCredentialsPolicy, PreconnectCompletionHandler&& completionHandler)
index 8030e69..b48f681 100644 (file)
@@ -60,7 +60,7 @@ public:
     void resumePendingRequests() final;
 
     void startPingLoad(WebCore::Frame&, WebCore::ResourceRequest&, const WebCore::HTTPHeaderMap& originalRequestHeaders, const WebCore::FetchOptions&, PingLoadCompletionHandler&&) final;
-    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&);
+    void didFinishPingLoad(uint64_t pingLoadIdentifier, WebCore::ResourceError&&, WebCore::ResourceResponse&&);
 
     void preconnectTo(WebCore::NetworkingContext&, const WebCore::URL&, WebCore::StoredCredentialsPolicy, PreconnectCompletionHandler&&) final;
     void didFinishPreconnection(uint64_t preconnectionIdentifier, WebCore::ResourceError&&);