Check http protocol when emitting resource timing entry

Currently when a resource load via file protocol fails, a resource
timing is emitted. We should only emit resource timing for resources
that are fetched over http(s) protocols or from web bundles.

This CL is to fix this issue. The  ResourceResponse::ShouldPopulateResourceTiming() method used for
checking protocol when load is successful checks if the
ResourceResponse::current_request_url_ is HTTP or the web bundle url
is valid.

However when the load fails, the ResourceResponse::current_request_url_
could be null, so we use ResourceRequest::url_, since we are only
checking for protocols.

Bug: 1472922
Change-Id: I674b2041f1911e9c6c04863dc38fc64a28be27af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4799574
Reviewed-by: Yoav Weiss <yoavweiss@chromium.org>
Commit-Queue: Hao Liu <haoliuk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1193611}
diff --git a/resource-timing/resource-timing-failed-fetch-web-bundle.tentative.html b/resource-timing/resource-timing-failed-fetch-web-bundle.tentative.html
new file mode 100644
index 0000000..b99183a
--- /dev/null
+++ b/resource-timing/resource-timing-failed-fetch-web-bundle.tentative.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>
+  Resource timing attributes are consistent for the same-origin subresources.
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-bundle/resources/test-helpers.js"></script>
+
+<body>
+  <script>
+    setup(() => {
+      assert_true(HTMLScriptElement.supports("webbundle"));
+    });
+
+    promise_test(async (t) => {
+      const script_url = 'dynamic1:resource1.js';
+      const non_exist_script_url = 'dynamic1:non_exist_resource.js';
+      // Using functions from /web-bundle/resources/test-helpers.js.
+      const element = createWebBundleElement(
+        "../web-bundle/resources/wbn/dynamic1.wbn",
+        /*resources=*/[script_url]
+      );
+
+      document.body.appendChild(element);
+
+      // Fetch the script that is in the web bundle.
+      const script = document.createElement("script");
+      script.type = "module";
+      script.src = script_url;
+      document.body.appendChild(script);
+
+      // Fetch the script that is not in the web bundle.
+      // Using functions from /web-bundle/resources/test-helpers.js.
+      await fetchAndWaitForReject(non_exist_script_url);
+
+      let resource1_entries = [];
+      let non_exist_resource_entries = [];
+
+      await new Promise((resolve) => {
+        new PerformanceObserver(list => {
+          resource1_entries.push(list.getEntries().filter(e => e.name.includes('resource1.js')));
+          non_exist_resource_entries.push(
+            list.getEntries().filter(e => e.name.includes('non_exist_resource.js')));
+          if (resource1_entries.length == 1 && non_exist_resource_entries.length == 1) {
+            resolve();
+          }
+        }
+        ).observe({ type: 'resource', buffered: true });
+      });
+    }, "Web bundle resources should have resource timing entries, even when the fetch failed.");
+  </script>
+</body>
\ No newline at end of file
diff --git a/resource-timing/resource-timing-failed-fetch.html b/resource-timing/resource-timing-failed-fetch.html
new file mode 100644
index 0000000..5bab39e
--- /dev/null
+++ b/resource-timing/resource-timing-failed-fetch.html
@@ -0,0 +1,34 @@
+<!doctype html>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="stylesheet" href="resources/empty_style.css">
+<link rel="stylesheet" href="resources/non_exist.css">
+
+<script>
+  promise_test(async () => {
+    const css_resource_timing_entries = await new Promise(resolve => {
+      new PerformanceObserver((list, observer) => {
+        let css_resource_timing_entries = list.getEntries().filter(e => e.name.includes('css'));
+        if (css_resource_timing_entries.length >= 2) {
+          resolve(css_resource_timing_entries);
+        }
+      }).observe({ 'type': 'resource', 'buffered': true });
+    });
+
+    assert_equals(css_resource_timing_entries.length, 2,
+      'There should be two resource timing entries for css resources');
+
+    assert_equals(css_resource_timing_entries.filter(
+      e => e.name.includes('empty_style.css')).length, 1,
+      'There should be one resource timing entry for successfully fetched resource.');
+
+    assert_equals(css_resource_timing_entries.filter(
+      e => e.name.includes('non_exist.css')).length, 1,
+      'There should be one resource timing entry for fetching failed resource.');
+
+  }, 'Resource fetched by HTTP protocol should have resource timing entry emitted, \
+  even when the fetch failed.');
+</script>
+
+</html>
\ No newline at end of file