Changeset 278391 in webkit
- Timestamp:
- Jun 2, 2021, 6:25:53 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 3 deleted
- 59 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/misc/webtiming-slow-load-expected.txt (modified) (1 diff)
-
LayoutTests/http/tests/misc/webtiming-slow-load.py (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server-expected.txt (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server.html (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/resource-timing/cross-origin-redirects-expected.txt (added)
-
LayoutTests/imported/w3c/web-platform-tests/resource-timing/cross-origin-redirects.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/entry-invariants.js (added)
-
LayoutTests/imported/w3c/web-platform-tests/resource-timing/resources/resource-loaders.js (added)
-
LayoutTests/platform/mac-wk1/TestExpectations (modified) (1 diff)
-
LayoutTests/platform/win/http/tests/misc/webtiming-one-redirect-expected.txt (added)
-
LayoutTests/platform/win/http/tests/misc/webtiming-slow-load-expected.txt (added)
-
LayoutTests/platform/win/http/tests/misc/webtiming-two-redirects-expected.txt (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Headers.cmake (modified) (5 diffs)
-
Source/WebCore/Sources.txt (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (15 diffs)
-
Source/WebCore/dom/Document.cpp (modified) (4 diffs)
-
Source/WebCore/dom/Document.h (modified) (3 diffs)
-
Source/WebCore/dom/DocumentEventTiming.h (added)
-
Source/WebCore/dom/DocumentTiming.h (deleted)
-
Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp (modified) (5 diffs)
-
Source/WebCore/inspector/agents/InspectorNetworkAgent.h (modified) (1 diff)
-
Source/WebCore/loader/DocumentLoadTiming.h (added)
-
Source/WebCore/loader/DocumentLoader.cpp (modified) (6 diffs)
-
Source/WebCore/loader/DocumentLoader.h (modified) (3 diffs)
-
Source/WebCore/loader/DocumentThreadableLoader.cpp (modified) (4 diffs)
-
Source/WebCore/loader/FrameLoader.cpp (modified) (2 diffs)
-
Source/WebCore/loader/LoadTiming.cpp (deleted)
-
Source/WebCore/loader/LoadTiming.h (deleted)
-
Source/WebCore/loader/ResourceLoadTiming.h (added)
-
Source/WebCore/loader/ResourceLoader.cpp (modified) (1 diff)
-
Source/WebCore/loader/ResourceLoader.h (modified) (3 diffs)
-
Source/WebCore/loader/ResourceTiming.cpp (modified) (3 diffs)
-
Source/WebCore/loader/ResourceTiming.h (modified) (5 diffs)
-
Source/WebCore/loader/ResourceTimingInformation.cpp (modified) (1 diff)
-
Source/WebCore/loader/SubresourceLoader.cpp (modified) (3 diffs)
-
Source/WebCore/loader/cache/CachedResource.h (modified) (1 diff)
-
Source/WebCore/loader/cache/CachedResourceLoader.cpp (modified) (2 diffs)
-
Source/WebCore/page/DOMWindow.cpp (modified) (1 diff)
-
Source/WebCore/page/Performance.cpp (modified) (1 diff)
-
Source/WebCore/page/Performance.h (modified) (2 diffs)
-
Source/WebCore/page/PerformanceNavigation.cpp (modified) (1 diff)
-
Source/WebCore/page/PerformanceNavigationTiming.cpp (modified) (5 diffs)
-
Source/WebCore/page/PerformanceNavigationTiming.h (modified) (3 diffs)
-
Source/WebCore/page/PerformanceResourceTiming.cpp (modified) (6 diffs)
-
Source/WebCore/page/PerformanceResourceTiming.h (modified) (2 diffs)
-
Source/WebCore/page/PerformanceTiming.cpp (modified) (15 diffs)
-
Source/WebCore/page/PerformanceTiming.h (modified) (2 diffs)
-
Source/WebCore/platform/network/NetworkLoadMetrics.h (modified) (16 diffs)
-
Source/WebCore/platform/network/ResourceHandle.cpp (modified) (1 diff)
-
Source/WebCore/platform/network/ResourceHandle.h (modified) (1 diff)
-
Source/WebCore/platform/network/ResourceHandleInternal.h (modified) (2 diffs)
-
Source/WebCore/platform/network/cocoa/NetworkLoadMetrics.mm (modified) (2 diffs)
-
Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm (modified) (10 diffs)
-
Source/WebCore/platform/network/curl/CurlContext.cpp (modified) (2 diffs)
-
Source/WebCore/platform/network/curl/CurlContext.h (modified) (2 diffs)
-
Source/WebCore/platform/network/curl/CurlRequest.cpp (modified) (3 diffs)
-
Source/WebCore/platform/network/curl/CurlRequest.h (modified) (2 diffs)
-
Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp (modified) (7 diffs)
-
Source/WebCore/platform/network/mac/ResourceHandleMac.mm (modified) (1 diff)
-
Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.h (modified) (2 diffs)
-
Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm (modified) (4 diffs)
-
Source/WebCore/platform/network/soup/ResourceRequest.h (modified) (4 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (modified) (1 diff)
-
Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (modified) (3 diffs)
-
Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp (modified) (5 diffs)
-
Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp (modified) (18 diffs)
-
Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r278388 r278391 1 2021-06-02 Alex Christensen <achristensen@webkit.org> 2 3 Fix WPT test resource-timing/cross-origin-redirects.html 4 https://bugs.webkit.org/show_bug.cgi?id=190523 5 <rdar://45227788> 6 7 Reviewed by Brady Eidson. 8 9 * http/tests/misc/webtiming-slow-load-expected.txt: 10 * http/tests/misc/webtiming-slow-load.py: 11 Our new metrics gathering now matches Firefox instead of Chrome in PerformanceResourceTiming::responseEnd in this edge case of a deprecated API. 12 Update expectations accordingly. 13 * platform/mac-wk1/TestExpectations: 14 Bringing this test to passing in WK2 makes it flaky in WK1 because we don't get good redirect timing data from CFNetwork through NSURLConnection. 15 * platform/win/http/tests/misc/webtiming-one-redirect-expected.txt: Added. 16 * platform/win/http/tests/misc/webtiming-slow-load-expected.txt: Copied from LayoutTests/http/tests/misc/webtiming-slow-load-expected.txt. 17 * platform/win/http/tests/misc/webtiming-two-redirects-expected.txt: Added. 18 The network layer is now responsible for counting redirects and providing redirect timings. 19 Our friend CFURLConnection doesn't have that ability, so it doesn't pass these tests any more. 20 It never supported any timing APIs and other tests are skipped. 21 1 22 2021-06-02 Amir Mark Jr <amir_mark@apple.com> 2 23 -
trunk/LayoutTests/http/tests/misc/webtiming-slow-load-expected.txt
r75120 r278391 6 6 PASS timing.requestStart is non-zero. 7 7 PASS timing.responseStart is non-zero. 8 PASS timing.responseEnd is 08 PASS timing.responseEnd is non-zero. 9 9 PASS successfullyParsed is true 10 10 -
trunk/LayoutTests/http/tests/misc/webtiming-slow-load.py
r273819 r278391 25 25 'shouldBeNonZero("timing.requestStart");\n' 26 26 'shouldBeNonZero("timing.responseStart");\n' 27 'shouldBe ("timing.responseEnd", "0");\n'27 'shouldBeNonZero("timing.responseEnd");\n' 28 28 '\n' 29 29 '</script>\n' -
trunk/LayoutTests/imported/w3c/ChangeLog
r278350 r278391 1 2021-06-02 Alex Christensen <achristensen@webkit.org> 2 3 Fix WPT test resource-timing/cross-origin-redirects.html 4 https://bugs.webkit.org/show_bug.cgi?id=190523 5 <rdar://45227788> 6 7 Reviewed by Brady Eidson. 8 9 * web-platform-tests/navigation-timing/nav2_test_redirect_server-expected.txt: 10 * web-platform-tests/navigation-timing/nav2_test_redirect_server.html: 11 Sometimes, with our use of Performance::reduceTimeResolution, the event times are equal to each other. 12 Allow this. 13 * web-platform-tests/resource-timing/cross-origin-redirects-expected.txt: Added. 14 * web-platform-tests/resource-timing/cross-origin-redirects.html: Added. 15 * web-platform-tests/resource-timing/resources/entry-invariants.js: Added. 16 (const.assert_all_equal_): 17 (const.assert_ordered_): 18 (const.assert_zeroed_): 19 (const.assert_not_negative_): 20 (const.assert_positive_): 21 (const.attribute_test_internal): 22 (async const): 23 (const.attribute_test_with_validator): 24 * web-platform-tests/resource-timing/resources/resource-loaders.js: Added. 25 (const.load.font.path.return.document.fonts.ready.then): 26 (const.load.stylesheet.async path): 27 (const.load.iframe.async path): 28 (const.load.script.async path): 29 (const.load.xhr_sync.async path): 30 1 31 2021-06-02 Martin Robinson <mrobinson@igalia.com> 2 32 -
trunk/LayoutTests/imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server-expected.txt
r277767 r278391 1 CONSOLE MESSAGE: Error: assert_true: Expected startTime to be no greater than redirectStart. expected true got false2 1 Description 3 2 … … 6 5 7 6 8 FAIL Navigation Timing 2 WPT Error: assert_true: Expected startTime to be no greater than redirectStart. expected true got false 7 PASS Navigation Timing 2 WPT 9 8 -
trunk/LayoutTests/imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server.html
r277767 r278391 14 14 function verifyTimingEventOrder(eventOrder, timingEntry) { 15 15 for (let i = 0; i < eventOrder.length - 1; i++) { 16 assert_true(timingEntry[eventOrder[i]] < timingEntry[eventOrder[i + 1]],16 assert_true(timingEntry[eventOrder[i]] <= timingEntry[eventOrder[i + 1]], 17 17 "Expected " + eventOrder[i] + " to be no greater than " + eventOrder[i + 1] + "."); 18 18 } -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r278387 r278391 583 583 webkit.org/b/159893 [ Debug ] imported/w3c/web-platform-tests/xhr/event-readystatechange-loaded.any.js [ Pass Failure ] 584 584 585 # NSURLConnection doesn't have an API to give us good timing for redirects. We do what we can with MonotonicTime::now() but this still fails sometimes. 586 imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server.html [ Pass Failure ] 587 585 588 webkit.org/b/160101 userscripts/window-onerror-for-isolated-world-3.html [ Pass Failure ] 586 589 -
trunk/Source/WebCore/ChangeLog
r278389 r278391 1 2021-06-02 Alex Christensen <achristensen@webkit.org> 2 3 Fix WPT test resource-timing/cross-origin-redirects.html 4 https://bugs.webkit.org/show_bug.cgi?id=190523 5 <rdar://45227788> 6 7 Reviewed by Brady Eidson. 8 9 Test: imported/w3c/web-platform-tests/resource-timing/cross-origin-redirects.html 10 11 This test took more to fix than I thought it would. We used to collect our timing data 12 from various sources into various structures, mostly based on Google's work from 2010 with 13 a few things tacked on to it. The timing specifications have changed considerably in the 14 last 11 years, and so should the shape of the structures we put the data into. 15 16 We used to have a LoadTiming structure in various places that claimed to contain the redirect times, 17 but markRedirectStart and markRedirectEnd were never called. Instead we tried to collect this data 18 from the SubResourceLoader and DocumentLoader reporting redirects in the web process. This wasn't great. 19 Redirect timing is best collected in the network process by the framework doing the redirecting, 20 and now we have the NSURLSessionTaskMetrics API to get the data we need. 21 22 I've made NetworkLoadMetrics the structure that contains all the network load metrics from the network process. 23 DocumentEventTiming is owned in the web process by the Document, and it contains the load event timing data. 24 ResourceLoadTiming is owned by the ResourceLoader, and it contains the fetch start and end times including the 25 parts of the fetch algorithm that happen in the web process. 26 DocumentLoadTiming inherits from it and is owned by the DocumentLoader, which reflects the fact that 27 PerformanceNavigationTiming inherits from PerformanceResourceTiming in the specs. 28 With these structures in place, we now have the infrastructure to collect timing data and expose it correctly. 29 30 Another thing that has changed is that these structures consistently store the timing data in the MonotonicTime type, 31 which is the number of seconds since the machine restarted. NetworkLoadMetrics used to confusingly store fetch 32 start time and then other network times as deltas from it, and we would pretend that fetch start time was the same 33 as the fetch start time in the web process and calculate everything from the deltas. This is an unfortunate 34 consequence of my younger self not realizing that the double values from NSURLConnection._timingData are values to 35 be put into [NSDate initWithTimeIntervalSinceReferenceDate] then pulled out with timeIntervalSince1970 to get 36 WallTime. I was confused because they weren't WallTime or MonotonicTime, so I only dealt with them as deltas 37 from each other. Consistently using MonotonicTime makes all this code much more straightforward. 38 39 I also use std::numeric_limits<uint64_t>::max() instead of std::numeric_limits<uint32_t>::max() as a sentinel value 40 for requestHeaderBytesSent and responseHeaderBytesReceived to make everything more sane. I'm not too worried about 41 the metrics of downloads of exactly 4GB, but they should also be fixed. 42 43 A consequence of collecting the redirect times in the network process is that we have to move the 44 SecurityOrigin::canRequest checks to see if the redirects are same-origin to ResourceHandle and NetworkDataTask. 45 46 * Headers.cmake: 47 * Sources.txt: 48 * WebCore.xcodeproj/project.pbxproj: 49 * dom/Document.cpp: 50 (WebCore::Document::setReadyState): 51 (WebCore::Document::finishedParsing): 52 (WebCore::Document::monotonicTimestamp const): 53 * dom/Document.h: 54 (WebCore::Document::eventTiming const): 55 (WebCore::Document::timing const): Deleted. 56 * dom/DocumentEventTiming.h: Copied from Source/WebCore/dom/DocumentTiming.h. 57 * inspector/agents/InspectorNetworkAgent.cpp: 58 (WebCore::InspectorNetworkAgent::buildObjectForTiming): 59 (WebCore::InspectorNetworkAgent::buildObjectForMetrics): 60 (WebCore::InspectorNetworkAgent::buildObjectForResourceResponse): 61 (WebCore::InspectorNetworkAgent::didFinishLoading): 62 * inspector/agents/InspectorNetworkAgent.h: 63 * loader/DocumentLoadTiming.h: Renamed from Source/WebCore/loader/LoadTiming.h. 64 (WebCore::DocumentLoadTiming::timeOrigin const): 65 (WebCore::DocumentLoadTiming::markUnloadEventStart): 66 (WebCore::DocumentLoadTiming::markUnloadEventEnd): 67 (WebCore::DocumentLoadTiming::markLoadEventStart): 68 (WebCore::DocumentLoadTiming::markLoadEventEnd): 69 (WebCore::DocumentLoadTiming::setHasSameOriginAsPreviousDocument): 70 (WebCore::DocumentLoadTiming::unloadEventStart const): 71 (WebCore::DocumentLoadTiming::unloadEventEnd const): 72 (WebCore::DocumentLoadTiming::loadEventStart const): 73 (WebCore::DocumentLoadTiming::loadEventEnd const): 74 (WebCore::DocumentLoadTiming::hasSameOriginAsPreviousDocument const): 75 * loader/DocumentLoader.cpp: 76 (WebCore::DocumentLoader::finishedLoading): 77 (WebCore::DocumentLoader::willSendRequest): 78 (WebCore::DocumentLoader::dataReceived): 79 (WebCore::DocumentLoader::startLoadingMainResource): 80 * loader/DocumentLoader.h: 81 (WebCore::DocumentLoader::timing const): 82 (WebCore::DocumentLoader::timing): 83 (WebCore::DocumentLoader::resetTiming): 84 * loader/DocumentThreadableLoader.cpp: 85 (WebCore::DocumentThreadableLoader::loadRequest): 86 * loader/FrameLoader.cpp: 87 (WebCore::FrameLoader::dispatchUnloadEvents): 88 * loader/LoadTiming.cpp: Removed. 89 * loader/ResourceLoadTiming.h: Renamed from Source/WebCore/dom/DocumentTiming.h. 90 (WebCore::ResourceLoadTiming::markStartTime): 91 (WebCore::ResourceLoadTiming::markEndTime): 92 (WebCore::ResourceLoadTiming::startTime const): 93 (WebCore::ResourceLoadTiming::endTime const): 94 (WebCore::ResourceLoadTiming::isolatedCopy const): 95 * loader/ResourceLoader.cpp: 96 (WebCore::ResourceLoader::init): 97 * loader/ResourceLoader.h: 98 (WebCore::ResourceLoader::loadTiming): 99 * loader/ResourceTiming.cpp: 100 (WebCore::ResourceTiming::fromMemoryCache): 101 (WebCore::ResourceTiming::fromLoad): 102 (WebCore::ResourceTiming::fromSynchronousLoad): 103 (WebCore::ResourceTiming::ResourceTiming): 104 (WebCore::ResourceTiming::isolatedCopy const): 105 (WebCore::ResourceTiming::fromCache): Deleted. 106 * loader/ResourceTiming.h: 107 (WebCore::ResourceTiming::resourceLoadTiming const): 108 (WebCore::ResourceTiming::ResourceTiming): 109 (WebCore::ResourceTiming::loadTiming const): Deleted. 110 * loader/ResourceTimingInformation.cpp: 111 * loader/SubresourceLoader.cpp: 112 (WebCore::SubresourceLoader::willSendRequestInternal): 113 (WebCore::SubresourceLoader::didFinishLoading): 114 * loader/cache/CachedResource.h: 115 * loader/cache/CachedResourceLoader.cpp: 116 (WebCore::CachedResourceLoader::requestResource): 117 * page/DOMWindow.cpp: 118 (WebCore::DOMWindow::performance const): 119 * page/Performance.cpp: 120 (WebCore::Performance::addNavigationTiming): 121 * page/Performance.h: 122 * page/PerformanceNavigation.cpp: 123 (WebCore::PerformanceNavigation::redirectCount const): 124 * page/PerformanceNavigationTiming.cpp: 125 (WebCore::PerformanceNavigationTiming::PerformanceNavigationTiming): 126 (WebCore::PerformanceNavigationTiming::millisecondsSinceOrigin const): 127 (WebCore::PerformanceNavigationTiming::sameOriginCheckFails const): 128 (WebCore::PerformanceNavigationTiming::unloadEventStart const): 129 (WebCore::PerformanceNavigationTiming::unloadEventEnd const): 130 (WebCore::PerformanceNavigationTiming::domInteractive const): 131 (WebCore::PerformanceNavigationTiming::domContentLoadedEventStart const): 132 (WebCore::PerformanceNavigationTiming::domContentLoadedEventEnd const): 133 (WebCore::PerformanceNavigationTiming::domComplete const): 134 (WebCore::PerformanceNavigationTiming::loadEventStart const): 135 (WebCore::PerformanceNavigationTiming::loadEventEnd const): 136 (WebCore::PerformanceNavigationTiming::redirectCount const): 137 * page/PerformanceNavigationTiming.h: 138 * page/PerformanceResourceTiming.cpp: 139 (WebCore::networkLoadTimeToDOMHighResTimeStamp): 140 (WebCore::fetchStart): 141 (WebCore::entryStartTime): 142 (WebCore::entryEndTime): 143 (WebCore::PerformanceResourceTiming::redirectStart const): 144 (WebCore::PerformanceResourceTiming::redirectEnd const): 145 (WebCore::PerformanceResourceTiming::fetchStart const): 146 (WebCore::PerformanceResourceTiming::domainLookupStart const): 147 (WebCore::PerformanceResourceTiming::domainLookupEnd const): 148 (WebCore::PerformanceResourceTiming::connectStart const): 149 (WebCore::PerformanceResourceTiming::connectEnd const): 150 (WebCore::PerformanceResourceTiming::secureConnectionStart const): 151 (WebCore::PerformanceResourceTiming::requestStart const): 152 (WebCore::PerformanceResourceTiming::responseStart const): 153 (WebCore::PerformanceResourceTiming::responseEnd const): 154 (WebCore::monotonicTimeToDOMHighResTimeStamp): Deleted. 155 (WebCore::PerformanceResourceTiming::networkLoadTimeToDOMHighResTimeStamp const): Deleted. 156 * page/PerformanceResourceTiming.h: 157 * page/PerformanceTiming.cpp: 158 (WebCore::PerformanceTiming::navigationStart const): 159 (WebCore::PerformanceTiming::unloadEventStart const): 160 (WebCore::PerformanceTiming::unloadEventEnd const): 161 (WebCore::PerformanceTiming::redirectStart const): 162 (WebCore::PerformanceTiming::redirectEnd const): 163 (WebCore::PerformanceTiming::fetchStart const): 164 (WebCore::PerformanceTiming::domainLookupStart const): 165 (WebCore::PerformanceTiming::domainLookupEnd const): 166 (WebCore::PerformanceTiming::connectStart const): 167 (WebCore::PerformanceTiming::connectEnd const): 168 (WebCore::PerformanceTiming::secureConnectionStart const): 169 (WebCore::PerformanceTiming::requestStart const): 170 (WebCore::PerformanceTiming::responseStart const): 171 (WebCore::PerformanceTiming::responseEnd const): 172 (WebCore::PerformanceTiming::domLoading const): 173 (WebCore::PerformanceTiming::domInteractive const): 174 (WebCore::PerformanceTiming::domContentLoadedEventStart const): 175 (WebCore::PerformanceTiming::domContentLoadedEventEnd const): 176 (WebCore::PerformanceTiming::domComplete const): 177 (WebCore::PerformanceTiming::loadEventStart const): 178 (WebCore::PerformanceTiming::loadEventEnd const): 179 (WebCore::PerformanceTiming::documentLoader const): 180 (WebCore::PerformanceTiming::documentEventTiming const): 181 (WebCore::PerformanceTiming::documentLoadTiming const): 182 (WebCore::PerformanceTiming::networkLoadMetrics const): 183 (WebCore::PerformanceTiming::monotonicTimeToIntegerMilliseconds const): 184 (WebCore::PerformanceTiming::documentTiming const): Deleted. 185 (WebCore::PerformanceTiming::loadTiming const): Deleted. 186 (WebCore::PerformanceTiming::resourceLoadTimeRelativeToFetchStart const): Deleted. 187 * page/PerformanceTiming.h: 188 * platform/network/NetworkLoadMetrics.h: 189 (WebCore::NetworkLoadMetrics::isolatedCopy const): 190 (WebCore::NetworkLoadMetrics::operator== const): 191 (WebCore::NetworkLoadMetrics::encode const): 192 (WebCore::NetworkLoadMetrics::decode): 193 * platform/network/ResourceHandle.cpp: 194 (WebCore::ResourceHandle::hasCrossOriginRedirect const): 195 (WebCore::ResourceHandle::setHasCrossOriginRedirect): 196 (WebCore::ResourceHandle::incrementRedirectCount): 197 (WebCore::ResourceHandle::redirectCount const): 198 (WebCore::ResourceHandle::startTimeBeforeRedirects const): 199 (WebCore::ResourceHandle::networkLoadMetrics): 200 (WebCore::ResourceHandle::setNetworkLoadMetrics): 201 * platform/network/ResourceHandle.h: 202 * platform/network/ResourceHandleInternal.h: 203 * platform/network/cocoa/NetworkLoadMetrics.mm: 204 (WebCore::dateToMonotonicTime): 205 (WebCore::packageTimingData): 206 (WebCore::copyTimingData): 207 * platform/network/cocoa/WebCoreNSURLSession.mm: 208 (networkLoadMetricsDate): 209 (-[WebCoreNSURLSessionTaskTransactionMetrics fetchStartDate]): 210 (-[WebCoreNSURLSessionTaskTransactionMetrics domainLookupStartDate]): 211 (-[WebCoreNSURLSessionTaskTransactionMetrics domainLookupEndDate]): 212 (-[WebCoreNSURLSessionTaskTransactionMetrics connectStartDate]): 213 (-[WebCoreNSURLSessionTaskTransactionMetrics secureConnectionStartDate]): 214 (-[WebCoreNSURLSessionTaskTransactionMetrics connectEndDate]): 215 (-[WebCoreNSURLSessionTaskTransactionMetrics requestStartDate]): 216 (-[WebCoreNSURLSessionTaskTransactionMetrics responseStartDate]): 217 (-[WebCoreNSURLSessionTaskTransactionMetrics responseEndDate]): 218 * platform/network/curl/CurlContext.cpp: 219 (WebCore::CurlHandle::getNetworkLoadMetrics): 220 * platform/network/curl/CurlContext.h: 221 * platform/network/curl/CurlRequest.cpp: 222 (WebCore::CurlRequest::didCompleteTransfer): 223 (WebCore::CurlRequest::networkLoadMetrics): 224 * platform/network/mac/ResourceHandleMac.mm: 225 (WebCore::ResourceHandle::start): 226 * platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.h: 227 * platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm: 228 (-[WebCoreResourceHandleAsOperationQueueDelegate connection:willSendRequest:redirectResponse:]): 229 (-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveResponse:]): 230 (-[WebCoreResourceHandleAsOperationQueueDelegate connectionDidFinishLoading:]): 231 1 232 2021-06-02 Alan Bujtas <zalan@apple.com> 2 233 -
trunk/Source/WebCore/Headers.cmake
r278354 r278391 440 440 dom/DeviceOrientationOrMotionPermissionState.h 441 441 dom/Document.h 442 dom/DocumentEventTiming.h 442 443 dom/DocumentFontLoader.h 443 444 dom/DocumentFragment.h … … 446 447 dom/DocumentMarkerController.h 447 448 dom/DocumentStorageAccess.h 448 dom/DocumentTiming.h449 449 dom/DocumentType.h 450 450 dom/Element.h … … 777 777 loader/CrossOriginPreflightResultCache.h 778 778 loader/CustomHeaderFields.h 779 loader/DocumentLoadTiming.h 779 780 loader/DocumentLoader.h 780 781 loader/DocumentWriter.h … … 797 798 loader/LinkLoaderClient.h 798 799 loader/LoadSchedulingMode.h 799 loader/LoadTiming.h800 800 loader/LoaderStrategy.h 801 801 loader/MediaResourceLoader.h … … 813 813 loader/ResourceLoadObserver.h 814 814 loader/ResourceLoadStatistics.h 815 loader/ResourceLoadTiming.h 815 816 loader/ResourceLoader.h 816 817 loader/ResourceLoaderOptions.h -
trunk/Source/WebCore/Sources.txt
r278354 r278391 1603 1603 loader/LinkLoader.cpp 1604 1604 loader/LinkPreloadResourceClients.cpp 1605 loader/LoadTiming.cpp1606 1605 loader/LoaderStrategy.cpp 1607 1606 loader/MediaResourceLoader.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r278354 r278391 1990 1990 5C53DCEA24468FB400A93124 /* ApplePaySetupWebCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C53DCCB2446449800A93124 /* ApplePaySetupWebCore.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1991 1991 5C5D2385227A0652000B9BDA /* CustomHeaderFields.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C5D2383227A063A000B9BDA /* CustomHeaderFields.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1992 5C6D0301265C211B002B64FE /* ResourceLoadTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C6D02FF265C211A002B64FE /* ResourceLoadTiming.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1992 1993 5C7C88D81D0F1F4A009D2F6D /* SocketProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1993 1994 5C9C2DB52241A67B00996B0B /* ContentRuleListResults.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C9C2DB32241A67300996B0B /* ContentRuleListResults.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2727 2728 868160D618766A130021E79D /* UserActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 868160D2187669C40021E79D /* UserActivity.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2728 2729 86BE340115058CB200CE0FD8 /* PerformanceEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */; }; 2729 86D982F7125C154000AD9E3D /* Document Timing.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D982F6125C154000AD9E3D /* DocumentTiming.h */; settings = {ATTRIBUTES = (Private, ); }; };2730 86D982F7125C154000AD9E3D /* DocumentEventTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D982F6125C154000AD9E3D /* DocumentEventTiming.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2730 2731 898785F5122E1EAC003AABDA /* JSFileReaderSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 898785F3122E1EAC003AABDA /* JSFileReaderSync.h */; }; 2731 8A12E35D11FA33280025836A /* LoadTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A12E35C11FA33280025836A /*LoadTiming.h */; settings = {ATTRIBUTES = (Private, ); }; };2732 8A12E35D11FA33280025836A /* DocumentLoadTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A12E35C11FA33280025836A /* DocumentLoadTiming.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2732 2733 8A309C9F123950BE00CB9204 /* NestingLevelIncrementer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A309C9E123950BE00CB9204 /* NestingLevelIncrementer.h */; }; 2733 2734 8A413AE01207BBA50082016E /* ScriptRunner.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A413ADE1207BBA50082016E /* ScriptRunner.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 9696 9697 5C688AA01D380509000B54FA /* ThreadableWebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableWebSocketChannel.cpp; sourceTree = "<group>"; }; 9697 9698 5C688AA21D38126F000B54FA /* SocketProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketProvider.cpp; sourceTree = "<group>"; }; 9699 5C6D02FF265C211A002B64FE /* ResourceLoadTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadTiming.h; sourceTree = "<group>"; }; 9698 9700 5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketProvider.h; sourceTree = "<group>"; }; 9699 9701 5C97A3361F5F7A6500105207 /* RectEdges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RectEdges.h; sourceTree = "<group>"; }; … … 11436 11438 85DF2F690AA3C74300AD64C5 /* HTMLCollection.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLCollection.idl; sourceTree = "<group>"; }; 11437 11439 85DF2F920AA3C9B600AD64C5 /* HTMLOptionsCollection.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLOptionsCollection.idl; sourceTree = "<group>"; }; 11438 861C2EA313FB4FDD00062ABB /* LoadTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadTiming.cpp; sourceTree = "<group>"; };11439 11440 862F129D18C1572C005C54AF /* CountedUserActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountedUserActivity.h; sourceTree = "<group>"; }; 11440 11441 86512EDB154A2AEE00A90426 /* PerformanceResourceTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceResourceTiming.cpp; sourceTree = "<group>"; }; … … 11447 11448 86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceEntry.h; sourceTree = "<group>"; }; 11448 11449 86BE33FC15058CB200CE0FD8 /* PerformanceEntry.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PerformanceEntry.idl; sourceTree = "<group>"; }; 11449 86D982F6125C154000AD9E3D /* Document Timing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentTiming.h; sourceTree = "<group>"; };11450 86D982F6125C154000AD9E3D /* DocumentEventTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentEventTiming.h; sourceTree = "<group>"; }; 11450 11451 8931DE5A14C44C44000DC9D2 /* JSBlobCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBlobCustom.cpp; sourceTree = "<group>"; }; 11451 11452 898785F2122E1EAC003AABDA /* JSFileReaderSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFileReaderSync.cpp; sourceTree = "<group>"; }; 11452 11453 898785F3122E1EAC003AABDA /* JSFileReaderSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFileReaderSync.h; sourceTree = "<group>"; }; 11453 8A12E35C11FA33280025836A /* LoadTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =LoadTiming.h; sourceTree = "<group>"; };11454 8A12E35C11FA33280025836A /* DocumentLoadTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentLoadTiming.h; sourceTree = "<group>"; }; 11454 11455 8A309C9E123950BE00CB9204 /* NestingLevelIncrementer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NestingLevelIncrementer.h; sourceTree = "<group>"; }; 11455 11456 8A413ADE1207BBA50082016E /* ScriptRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptRunner.h; sourceTree = "<group>"; }; … … 27799 27800 93E227DB0AF589AD00D48324 /* DocumentLoader.cpp */, 27800 27801 656D371E0ADBA5DE00A4554D /* DocumentLoader.h */, 27802 8A12E35C11FA33280025836A /* DocumentLoadTiming.h */, 27801 27803 0B9056150F2578BE0095FF6A /* DocumentThreadableLoader.cpp */, 27802 27804 0B9056160F2578BE0095FF6A /* DocumentThreadableLoader.h */, … … 27843 27845 51E6820F16387302003BBF3C /* LoaderStrategy.h */, 27844 27846 E47FC8A125B84D71005495FC /* LoadSchedulingMode.h */, 27845 861C2EA313FB4FDD00062ABB /* LoadTiming.cpp */,27846 8A12E35C11FA33280025836A /* LoadTiming.h */,27847 27847 CEEFCD7719DB31F7003876D7 /* MediaResourceLoader.cpp */, 27848 27848 CEEFCD7819DB31F7003876D7 /* MediaResourceLoader.h */, … … 27879 27879 7A929CA11C598378004DF226 /* ResourceLoadStatistics.cpp */, 27880 27880 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */, 27881 5C6D02FF265C211A002B64FE /* ResourceLoadTiming.h */, 27881 27882 A5CE9F3E1E4C416B001BBE7C /* ResourceTiming.cpp */, 27882 27883 A5CE9F3C1E4BC586001BBE7C /* ResourceTiming.h */, … … 30565 30566 6548E24809E1E04D00AF8020 /* Document.idl */, 30566 30567 8329A4171EC25B2B008ED4BE /* DocumentAndElementEventHandlers.idl */, 30568 86D982F6125C154000AD9E3D /* DocumentEventTiming.h */, 30567 30569 A8185F3459765765005826D9 /* DocumentFontLoader.cpp */, 30568 30570 A8185F3559765765005826D9 /* DocumentFontLoader.h */, … … 30582 30584 6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */, 30583 30585 6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */, 30584 86D982F6125C154000AD9E3D /* DocumentTiming.h */,30585 30586 7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */, 30586 30587 7CE7FA591EF882300060C9D6 /* DocumentTouch.h */, … … 32453 32454 7EE6846F12D26E3800E73215 /* DNSResolveQueueCFNet.h in Headers */, 32454 32455 A8185F4009765766005826D9 /* Document.h in Headers */, 32456 86D982F7125C154000AD9E3D /* DocumentEventTiming.h in Headers */, 32455 32457 A8185F4509765766005826D9 /* DocumentFontLoader.h in Headers */, 32456 32458 A8185F3D09765766005826D9 /* DocumentFragment.h in Headers */, … … 32458 32460 41826BF223FB597700B922B1 /* DocumentIdentifier.h in Headers */, 32459 32461 656D37360ADBA5DE00A4554D /* DocumentLoader.h in Headers */, 32462 8A12E35D11FA33280025836A /* DocumentLoadTiming.h in Headers */, 32460 32463 ED2BA83C09A24B91006C0AC4 /* DocumentMarker.h in Headers */, 32461 32464 CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */, … … 32468 32471 71729F7B20F3BA4900801CE6 /* DocumentTimelineOptions.h in Headers */, 32469 32472 7181A16C244F0F40007D8A24 /* DocumentTimelinesController.h in Headers */, 32470 86D982F7125C154000AD9E3D /* DocumentTiming.h in Headers */,32471 32473 A8185F3909765766005826D9 /* DocumentType.h in Headers */, 32472 32474 973889A1116EA9DC00ADF313 /* DocumentWriter.h in Headers */, … … 34216 34218 51E6821016387302003BBF3C /* LoaderStrategy.h in Headers */, 34217 34219 E47FC8A325B84D72005495FC /* LoadSchedulingMode.h in Headers */, 34218 8A12E35D11FA33280025836A /* LoadTiming.h in Headers */,34219 34220 06E81ED70AB5D5E900C87837 /* LocalCurrentGraphicsContext.h in Headers */, 34220 34221 1C43DE6B22AB4B8A001527D9 /* LocalCurrentTraitCollection.h in Headers */, … … 35022 35023 E4295FA412B0614E00D1ACE0 /* ResourceLoadPriority.h in Headers */, 35023 35024 7A929CA71C598AA9004DF226 /* ResourceLoadStatistics.h in Headers */, 35025 5C6D0301265C211B002B64FE /* ResourceLoadTiming.h in Headers */, 35024 35026 7EE6846D12D26E3800E79415 /* ResourceRequest.h in Headers */, 35025 35027 514C767D0CE923A1007EF3CD /* ResourceRequestBase.h in Headers */, -
trunk/Source/WebCore/dom/Document.cpp
r278331 r278391 1384 1384 switch (readyState) { 1385 1385 case Loading: 1386 if (!m_ documentTiming.domLoading)1387 m_ documentTiming.domLoading = MonotonicTime::now();1386 if (!m_eventTiming.domLoading) 1387 m_eventTiming.domLoading = MonotonicTime::now(); 1388 1388 break; 1389 1389 case Complete: 1390 if (!m_ documentTiming.domComplete)1391 m_ documentTiming.domComplete = MonotonicTime::now();1390 if (!m_eventTiming.domComplete) 1391 m_eventTiming.domComplete = MonotonicTime::now(); 1392 1392 FALLTHROUGH; 1393 1393 case Interactive: 1394 if (!m_ documentTiming.domInteractive)1395 m_ documentTiming.domInteractive = MonotonicTime::now();1394 if (!m_eventTiming.domInteractive) 1395 m_eventTiming.domInteractive = MonotonicTime::now(); 1396 1396 break; 1397 1397 } … … 6035 6035 scriptRunner().documentFinishedParsing(); 6036 6036 6037 if (!m_ documentTiming.domContentLoadedEventStart)6038 m_ documentTiming.domContentLoadedEventStart = MonotonicTime::now();6037 if (!m_eventTiming.domContentLoadedEventStart) 6038 m_eventTiming.domContentLoadedEventStart = MonotonicTime::now(); 6039 6039 6040 6040 // FIXME: Schedule a task to fire DOMContentLoaded event instead. See webkit.org/b/82931 … … 6042 6042 dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, Event::CanBubble::Yes, Event::IsCancelable::No)); 6043 6043 6044 if (!m_ documentTiming.domContentLoadedEventEnd)6045 m_ documentTiming.domContentLoadedEventEnd = MonotonicTime::now();6044 if (!m_eventTiming.domContentLoadedEventEnd) 6045 m_eventTiming.domContentLoadedEventEnd = MonotonicTime::now(); 6046 6046 6047 6047 if (RefPtr<Frame> frame = this->frame()) { … … 6746 6746 auto* loader = this->loader(); 6747 6747 if (!loader) 6748 return 0; 6749 6750 return loader->timing().secondsSinceStartTime(MonotonicTime::now()).seconds(); 6748 return 0.0; 6749 return (MonotonicTime::now() - loader->timing().startTime()).seconds(); 6751 6750 } 6752 6751 -
trunk/Source/WebCore/dom/Document.h
r278253 r278391 33 33 #include "ContainerNode.h" 34 34 #include "DisabledAdaptations.h" 35 #include "DocumentEventTiming.h" 35 36 #include "DocumentIdentifier.h" 36 37 #include "DocumentTimelinesController.h" 37 #include "DocumentTiming.h"38 38 #include "ElementIdentifier.h" 39 39 #include "FocusOptions.h" … … 1208 1208 #endif 1209 1209 1210 const DocumentTiming& timing() const { return m_documentTiming; }1211 1212 1210 WEBCORE_EXPORT double monotonicTimestamp() const; 1211 const DocumentEventTiming& eventTiming() const { return m_eventTiming; } 1213 1212 1214 1213 int requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&); … … 1919 1918 OptionSet<DisabledAdaptations> m_disabledAdaptations; 1920 1919 1921 Document Timing m_documentTiming;1920 DocumentEventTiming m_eventTiming; 1922 1921 1923 1922 RefPtr<MediaQueryMatcher> m_mediaQueryMatcher; -
trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp
r278253 r278391 214 214 } 215 215 216 Ref<Protocol::Network::ResourceTiming> InspectorNetworkAgent::buildObjectForTiming(const NetworkLoadMetrics* timing, ResourceLoader& resourceLoader) 217 { 218 auto& loadTiming = resourceLoader.loadTiming(); 219 216 Ref<Protocol::Network::ResourceTiming> InspectorNetworkAgent::buildObjectForTiming(const NetworkLoadMetrics& timing, ResourceLoader& resourceLoader) 217 { 220 218 auto elapsedTimeSince = [&] (const MonotonicTime& time) { 221 219 return m_environment.executionStopwatch().elapsedTimeSince(time).seconds(); 222 220 }; 223 std::optional<NetworkLoadMetrics> empty;224 if (!timing) {225 empty.emplace();226 timing = &empty.value();227 } 221 auto millisecondsSinceFetchStart = [&] (const MonotonicTime& time) { 222 if (!time) 223 return 0.0; 224 return (time - timing.fetchStart).milliseconds(); 225 }; 228 226 229 227 return Protocol::Network::ResourceTiming::create() 230 .setStartTime(elapsedTimeSince( loadTiming.startTime()))231 .setRedirectStart(elapsedTimeSince( loadTiming.redirectStart()))232 .setRedirectEnd(elapsedTimeSince( loadTiming.redirectEnd()))233 .setFetchStart(elapsedTimeSince( loadTiming.fetchStart()))234 .setDomainLookupStart( timing->domainLookupStart.milliseconds())235 .setDomainLookupEnd( timing->domainLookupEnd.milliseconds())236 .setConnectStart( timing->connectStart.milliseconds())237 .setConnectEnd( timing->connectEnd.milliseconds())238 .setSecureConnectionStart( timing->secureConnectionStart.milliseconds())239 .setRequestStart( timing->requestStart.milliseconds())240 .setResponseStart( timing->responseStart.milliseconds())241 .setResponseEnd( timing->responseEnd.milliseconds())228 .setStartTime(elapsedTimeSince(resourceLoader.loadTiming().startTime())) 229 .setRedirectStart(elapsedTimeSince(timing.redirectStart)) 230 .setRedirectEnd(elapsedTimeSince(timing.fetchStart)) 231 .setFetchStart(elapsedTimeSince(timing.fetchStart)) 232 .setDomainLookupStart(millisecondsSinceFetchStart(timing.domainLookupStart)) 233 .setDomainLookupEnd(millisecondsSinceFetchStart(timing.domainLookupEnd)) 234 .setConnectStart(millisecondsSinceFetchStart(timing.connectStart)) 235 .setConnectEnd(millisecondsSinceFetchStart(timing.connectEnd)) 236 .setSecureConnectionStart(millisecondsSinceFetchStart(timing.secureConnectionStart)) 237 .setRequestStart(millisecondsSinceFetchStart(timing.requestStart)) 238 .setResponseStart(millisecondsSinceFetchStart(timing.responseStart)) 239 .setResponseEnd(millisecondsSinceFetchStart(timing.responseEnd)) 242 240 .release(); 243 241 } … … 275 273 metrics->setRequestHeaders(buildObjectForHeaders(networkLoadMetrics.requestHeaders)); 276 274 277 if (networkLoadMetrics.requestHeaderBytesSent != std::numeric_limits<uint 32_t>::max())275 if (networkLoadMetrics.requestHeaderBytesSent != std::numeric_limits<uint64_t>::max()) 278 276 metrics->setRequestHeaderBytesSent(networkLoadMetrics.requestHeaderBytesSent); 279 277 if (networkLoadMetrics.requestBodyBytesSent != std::numeric_limits<uint64_t>::max()) 280 278 metrics->setRequestBodyBytesSent(networkLoadMetrics.requestBodyBytesSent); 281 if (networkLoadMetrics.responseHeaderBytesReceived != std::numeric_limits<uint 32_t>::max())279 if (networkLoadMetrics.responseHeaderBytesReceived != std::numeric_limits<uint64_t>::max()) 282 280 metrics->setResponseHeaderBytesReceived(networkLoadMetrics.responseHeaderBytesReceived); 283 281 if (networkLoadMetrics.responseBodyBytesReceived != std::numeric_limits<uint64_t>::max()) … … 354 352 .release(); 355 353 356 if (resourceLoader) 357 responseObject->setTiming(buildObjectForTiming(response.deprecatedNetworkLoadMetricsOrNull(), *resourceLoader)); 354 if (resourceLoader) { 355 auto* metrics = response.deprecatedNetworkLoadMetricsOrNull(); 356 responseObject->setTiming(buildObjectForTiming(metrics ? *metrics : NetworkLoadMetrics { }, *resourceLoader)); 357 } 358 358 359 359 if (auto& certificateInfo = response.certificateInfo()) { … … 593 593 } 594 594 595 void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics, ResourceLoader* resourceLoader)595 void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics, ResourceLoader*) 596 596 { 597 597 if (m_hiddenRequestIdentifiers.remove(identifier)) … … 599 599 600 600 double elapsedFinishTime; 601 if (resourceLoader && networkLoadMetrics.isComplete()) { 602 MonotonicTime fetchStart = resourceLoader->loadTiming().fetchStart(); 603 Seconds fetchStartInInspector = m_environment.executionStopwatch().elapsedTimeSince(fetchStart); 604 elapsedFinishTime = (fetchStartInInspector + networkLoadMetrics.responseEnd).seconds(); 605 } else 601 if (networkLoadMetrics.isComplete()) 602 elapsedFinishTime = m_environment.executionStopwatch().elapsedTimeSince(networkLoadMetrics.responseEnd).seconds(); 603 else 606 604 elapsedFinishTime = timestamp(); 607 605 -
trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.h
r278253 r278391 150 150 151 151 Ref<Inspector::Protocol::Network::Initiator> buildInitiatorObject(Document*, const ResourceRequest* = nullptr); 152 Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics *, ResourceLoader&);152 Ref<Inspector::Protocol::Network::ResourceTiming> buildObjectForTiming(const NetworkLoadMetrics&, ResourceLoader&); 153 153 Ref<Inspector::Protocol::Network::Metrics> buildObjectForMetrics(const NetworkLoadMetrics&); 154 154 RefPtr<Inspector::Protocol::Network::Response> buildObjectForResourceResponse(const ResourceResponse&, ResourceLoader*); -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r278253 r278391 469 469 maybeFinishLoadingMultipartContent(); 470 470 471 MonotonicTime responseEndTime = m_timeOfLastDataReceived ? m_timeOfLastDataReceived : MonotonicTime::now(); 472 timing().setResponseEnd(responseEndTime); 473 471 timing().markEndTime(); 472 474 473 commitIfReady(); 475 474 if (!frameLoader()) … … 638 637 } 639 638 640 ASSERT(timing(). fetchStart());639 ASSERT(timing().startTime()); 641 640 if (didReceiveRedirectResponse) { 642 641 // If the redirecting url is not allowed to display content from the target origin, … … 656 655 return completionHandler(WTFMove(newRequest)); 657 656 } 658 timing().addRedirect(redirectResponse.url(), newRequest.url());659 657 } 660 658 … … 1283 1281 1284 1282 m_applicationCacheHost->mainResourceDataReceived(data, length, -1, false); 1285 m_timeOfLastDataReceived = MonotonicTime::now();1286 1283 1287 1284 if (!isMultipartReplacingLoad()) … … 1915 1912 { 1916 1913 m_mainDocumentError = ResourceError(); 1917 timing().markStartTime AndFetchStart();1914 timing().markStartTime(); 1918 1915 ASSERT(!m_mainResource); 1919 1916 ASSERT(!m_loadingMainResource); … … 1936 1933 1937 1934 ASSERT(timing().startTime()); 1938 ASSERT(timing().fetchStart());1939 1935 1940 1936 willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = WTFMove(protectedThis)] (ResourceRequest&& request) mutable { -
trunk/Source/WebCore/loader/DocumentLoader.h
r278253 r278391 36 36 #include "DeviceOrientationOrMotionPermissionState.h" 37 37 #include "DocumentIdentifier.h" 38 #include "DocumentLoadTiming.h" 38 39 #include "DocumentWriter.h" 39 40 #include "FrameDestructionObserver.h" 40 41 #include "LinkIcon.h" 41 #include "LoadTiming.h"42 42 #include "NavigationAction.h" 43 43 #include "ResourceError.h" … … 352 352 void takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loads); 353 353 354 LoadTiming& timing() { return m_loadTiming; } 355 void resetTiming() { m_loadTiming = LoadTiming(); } 354 const DocumentLoadTiming& timing() const { return m_loadTiming; } 355 DocumentLoadTiming& timing() { return m_loadTiming; } 356 void resetTiming() { m_loadTiming = { }; } 356 357 357 358 // The WebKit layer calls this function when it's ready for the data to actually be added to the document. … … 597 598 598 599 bool m_loadingMainResource { false }; 599 LoadTiming m_loadTiming; 600 601 MonotonicTime m_timeOfLastDataReceived; 600 DocumentLoadTiming m_loadTiming; 601 602 602 unsigned long m_identifierForLoadWithoutResourceLoader { 0 }; 603 603 -
trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp
r278253 r278391 46 46 #include "InspectorInstrumentation.h" 47 47 #include "LegacySchemeRegistry.h" 48 #include "LoadTiming.h"49 48 #include "LoaderStrategy.h" 50 49 #include "MixedContentChecker.h" … … 585 584 ASSERT(m_options.credentials != FetchOptions::Credentials::Omit); 586 585 587 LoadTiming loadTiming;588 loadTiming.markStartTime AndFetchStart();586 ResourceLoadTiming loadTiming; 587 loadTiming.markStartTime(); 589 588 590 589 // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. … … 600 599 } 601 600 602 loadTiming. setResponseEnd(MonotonicTime::now());601 loadTiming.markEndTime(); 603 602 604 603 if (!error.isNull() && response.httpStatusCode() <= 0) { … … 655 654 656 655 const auto* timing = response.deprecatedNetworkLoadMetricsOrNull(); 657 std::optional<NetworkLoadMetrics> empty; 658 if (!timing) { 659 empty.emplace(); 660 timing = &empty.value(); 661 } 662 auto resourceTiming = ResourceTiming::fromSynchronousLoad(requestURL, m_options.initiator, loadTiming, *timing, response, securityOrigin()); 656 auto resourceTiming = ResourceTiming::fromSynchronousLoad(requestURL, m_options.initiator, loadTiming, timing ? *timing : NetworkLoadMetrics { }, response, securityOrigin()); 663 657 if (options().initiatorContext == InitiatorContext::Worker) 664 658 finishedTimingForWorkerLoad(resourceTiming); -
trunk/Source/WebCore/loader/FrameLoader.cpp
r278253 r278391 86 86 #include "InspectorInstrumentation.h" 87 87 #include "LinkLoader.h" 88 #include "LoadTiming.h"89 88 #include "LoaderStrategy.h" 90 89 #include "Logging.h" … … 3304 3303 if (m_frame.document()->backForwardCacheState() == Document::NotInBackForwardCache) { 3305 3304 Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, Event::CanBubble::No, Event::IsCancelable::No)); 3306 // The DocumentLoader (and thus its LoadTiming) might get destroyed3305 // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed 3307 3306 // while dispatching the event, so protect it to prevent writing the end 3308 3307 // time into freed memory. 3309 3308 RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader; 3309 auto* timing = documentLoader ? &documentLoader->timing() : nullptr; 3310 3310 m_pageDismissalEventBeingDispatched = PageDismissalType::Unload; 3311 if (documentLoader && documentLoader->timing().startTime() && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) { 3312 auto& timing = documentLoader->timing(); 3313 timing.markUnloadEventStart(); 3314 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document()); 3315 timing.markUnloadEventEnd(); 3316 } else 3317 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document()); 3311 if (timing && !timing->unloadEventStart()) 3312 timing->markUnloadEventStart(); 3313 m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document()); 3314 if (timing && !timing->unloadEventEnd()) 3315 timing->markUnloadEventEnd(); 3318 3316 } 3319 3317 } -
trunk/Source/WebCore/loader/ResourceLoader.cpp
r278185 r278391 138 138 ASSERT(!m_documentLoader->isSubstituteLoadPending(this)); 139 139 140 m_loadTiming.markStartTime AndFetchStart();141 140 m_loadTiming.markStartTime(); 141 142 142 m_defersLoading = m_options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && m_frame->page()->defersLoading(); 143 143 -
trunk/Source/WebCore/loader/ResourceLoader.h
r277767 r278391 29 29 #pragma once 30 30 31 #include "LoadTiming.h"32 31 #include "ResourceHandleClient.h" 32 #include "ResourceLoadTiming.h" 33 33 #include "ResourceLoaderOptions.h" 34 34 #include "ResourceLoaderTypes.h" … … 141 141 void willSwitchToSubstituteResource(); 142 142 143 const LoadTiming& loadTiming() { return m_loadTiming; }143 const ResourceLoadTiming& loadTiming() { return m_loadTiming; } 144 144 145 145 #if PLATFORM(COCOA) … … 179 179 RefPtr<DocumentLoader> m_documentLoader; 180 180 ResourceResponse m_response; 181 LoadTiming m_loadTiming;181 ResourceLoadTiming m_loadTiming; 182 182 #if USE(QUICK_LOOK) 183 183 std::unique_ptr<LegacyPreviewLoader> m_previewLoader; -
trunk/Source/WebCore/loader/ResourceTiming.cpp
r277767 r278391 58 58 } 59 59 60 ResourceTiming ResourceTiming::from Cache(const URL& url, const String& initiator, constLoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)60 ResourceTiming ResourceTiming::fromMemoryCache(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin) 61 61 { 62 62 return ResourceTiming(url, initiator, loadTiming, response, securityOrigin); 63 63 } 64 64 65 ResourceTiming ResourceTiming::fromLoad(CachedResource& resource, const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const SecurityOrigin& securityOrigin)65 ResourceTiming ResourceTiming::fromLoad(CachedResource& resource, const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const SecurityOrigin& securityOrigin) 66 66 { 67 67 return ResourceTiming(url, initiator, loadTiming, networkLoadMetrics, resource.response(), securityOrigin); 68 68 } 69 69 70 ResourceTiming ResourceTiming::fromSynchronousLoad(const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)70 ResourceTiming ResourceTiming::fromSynchronousLoad(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin) 71 71 { 72 72 return ResourceTiming(url, initiator, loadTiming, networkLoadMetrics, response, securityOrigin); 73 73 } 74 74 75 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const LoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)75 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin) 76 76 : m_url(url) 77 77 , m_initiator(initiator) 78 , m_ loadTiming(loadTiming)78 , m_resourceLoadTiming(loadTiming) 79 79 , m_allowTimingDetails(passesTimingAllowCheck(response, securityOrigin)) 80 80 { … … 82 82 } 83 83 84 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)84 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const ResourceLoadTiming& timing, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin) 85 85 : m_url(url) 86 86 , m_initiator(initiator) 87 , m_ loadTiming(loadTiming)87 , m_resourceLoadTiming(timing) 88 88 , m_networkLoadMetrics(networkLoadMetrics) 89 89 , m_allowTimingDetails(passesTimingAllowCheck(response, securityOrigin)) … … 107 107 ResourceTiming ResourceTiming::isolatedCopy() const 108 108 { 109 return ResourceTiming(m_url.isolatedCopy(), m_initiator.isolatedCopy(), m_loadTiming.isolatedCopy(), m_networkLoadMetrics.isolatedCopy(), m_allowTimingDetails, crossThreadCopy(m_serverTiming)); 109 return ResourceTiming( 110 m_url.isolatedCopy(), 111 m_initiator.isolatedCopy(), 112 m_resourceLoadTiming.isolatedCopy(), 113 m_networkLoadMetrics.isolatedCopy(), 114 m_allowTimingDetails, 115 crossThreadCopy(m_serverTiming) 116 ); 110 117 } 111 118 -
trunk/Source/WebCore/loader/ResourceTiming.h
r277767 r278391 26 26 #pragma once 27 27 28 #include "LoadTiming.h"29 28 #include "NetworkLoadMetrics.h" 29 #include "ResourceLoadTiming.h" 30 30 #include "ServerTiming.h" 31 31 #include <wtf/URL.h> … … 36 36 class PerformanceServerTiming; 37 37 class ResourceResponse; 38 class ResourceLoadTiming; 38 39 class SecurityOrigin; 39 40 … … 41 42 WTF_MAKE_FAST_ALLOCATED; 42 43 public: 43 static ResourceTiming from Cache(const URL&, const String& initiator, constLoadTiming&, const ResourceResponse&, const SecurityOrigin&);44 static ResourceTiming fromLoad(CachedResource&, const URL&, const String& initiator, const LoadTiming&, const NetworkLoadMetrics&, const SecurityOrigin&);45 static ResourceTiming fromSynchronousLoad(const URL&, const String& initiator, const LoadTiming&, const NetworkLoadMetrics&, const ResourceResponse&, const SecurityOrigin&);44 static ResourceTiming fromMemoryCache(const URL&, const String& initiator, const ResourceLoadTiming&, const ResourceResponse&, const SecurityOrigin&); 45 static ResourceTiming fromLoad(CachedResource&, const URL&, const String& initiator, const ResourceLoadTiming&, const NetworkLoadMetrics&, const SecurityOrigin&); 46 static ResourceTiming fromSynchronousLoad(const URL&, const String& initiator, const ResourceLoadTiming&, const NetworkLoadMetrics&, const ResourceResponse&, const SecurityOrigin&); 46 47 47 48 const URL& url() const { return m_url; } 48 49 const String& initiator() const { return m_initiator; } 49 const LoadTiming& loadTiming() const { return m_loadTiming; }50 const ResourceLoadTiming& resourceLoadTiming() const { return m_resourceLoadTiming; } 50 51 const NetworkLoadMetrics& networkLoadMetrics() const { return m_networkLoadMetrics; } 51 52 bool allowTimingDetails() const { return m_allowTimingDetails; } … … 56 57 57 58 private: 58 ResourceTiming(const URL&, const String& initiator, const LoadTiming&, const NetworkLoadMetrics&, const ResourceResponse&, const SecurityOrigin&);59 ResourceTiming(const URL&, const String& initiator, const LoadTiming&, const ResourceResponse&, const SecurityOrigin&);60 ResourceTiming(URL&& url, String&& initiator, LoadTiming&& loadTiming, NetworkLoadMetrics&& networkLoadMetrics, bool allowTimingDetails, Vector<ServerTiming>&& serverTiming)59 ResourceTiming(const URL&, const String& initiator, const ResourceLoadTiming&, const NetworkLoadMetrics&, const ResourceResponse&, const SecurityOrigin&); 60 ResourceTiming(const URL&, const String& initiator, const ResourceLoadTiming&, const ResourceResponse&, const SecurityOrigin&); 61 ResourceTiming(URL&& url, String&& initiator, const ResourceLoadTiming& resourceLoadTiming, NetworkLoadMetrics&& networkLoadMetrics, bool allowTimingDetails, Vector<ServerTiming>&& serverTiming) 61 62 : m_url(WTFMove(url)) 62 63 , m_initiator(WTFMove(initiator)) 63 , m_ loadTiming(WTFMove(loadTiming))64 , m_resourceLoadTiming(resourceLoadTiming) 64 65 , m_networkLoadMetrics(WTFMove(networkLoadMetrics)) 65 66 , m_allowTimingDetails(allowTimingDetails) … … 71 72 URL m_url; 72 73 String m_initiator; 73 LoadTiming m_loadTiming;74 ResourceLoadTiming m_resourceLoadTiming; 74 75 NetworkLoadMetrics m_networkLoadMetrics; 75 76 bool m_allowTimingDetails { false }; -
trunk/Source/WebCore/loader/ResourceTimingInformation.cpp
r278119 r278391 33 33 #include "FrameLoader.h" 34 34 #include "HTMLFrameOwnerElement.h" 35 #include "LoadTiming.h"36 35 #include "Performance.h" 37 36 #include "ResourceTiming.h" -
trunk/Source/WebCore/loader/SubresourceLoader.cpp
r278253 r278391 311 311 return completionHandler(WTFMove(newRequest)); 312 312 } 313 m_loadTiming.addRedirect(redirectResponse.url(), newRequest.url());314 313 m_resource->redirectReceived(WTFMove(newRequest), redirectResponse, [this, protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), continueWillSendRequest = WTFMove(continueWillSendRequest)] (ResourceRequest&& request) mutable { 315 314 RELEASE_LOG_IF_ALLOWED("willSendRequestInternal: resource done notifying clients"); … … 734 733 CachedResourceHandle<CachedResource> protectResource(m_resource); 735 734 736 // FIXME: Remove this with deprecatedNetworkLoadMetrics. 737 m_loadTiming.setResponseEnd(MonotonicTime::now()); 735 m_loadTiming.markEndTime(); 738 736 739 737 if (networkLoadMetrics.isComplete()) … … 744 742 // that they populated partial load timing information on the ResourceResponse. 745 743 const auto* timing = m_resource->response().deprecatedNetworkLoadMetricsOrNull(); 746 std::optional<NetworkLoadMetrics> empty; 747 if (!timing) { 748 empty.emplace(); 749 timing = &empty.value(); 750 } 751 reportResourceTiming(*timing); 744 reportResourceTiming(timing ? *timing : NetworkLoadMetrics { }); 752 745 } 753 746 -
trunk/Source/WebCore/loader/cache/CachedResource.h
r278253 r278391 46 46 class CachedResourceRequest; 47 47 class CookieJar; 48 class LoadTiming;49 48 class MemoryCache; 50 49 class NetworkLoadMetrics; -
trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp
r278185 r278391 961 961 } 962 962 963 LoadTiming loadTiming;964 loadTiming.markStartTime AndFetchStart();963 ResourceLoadTiming loadTiming; 964 loadTiming.markStartTime(); 965 965 InitiatorContext initiatorContext = request.options().initiatorContext; 966 966 … … 1022 1022 return makeUnexpected(WTFMove(error)); 1023 1023 logMemoryCacheResourceRequest(&frame, DiagnosticLoggingKeys::memoryCacheEntryDecisionKey(), DiagnosticLoggingKeys::usedKey()); 1024 loadTiming. setResponseEnd(MonotonicTime::now());1024 loadTiming.markEndTime(); 1025 1025 1026 1026 memoryCache.resourceAccessed(*resource); 1027 1027 1028 1028 if (document() && !resource->isLoading()) { 1029 auto resourceTiming = ResourceTiming::from Cache(url, request.initiatorName(), loadTiming, resource->response(), *request.origin());1029 auto resourceTiming = ResourceTiming::fromMemoryCache(url, request.initiatorName(), loadTiming, resource->response(), *request.origin()); 1030 1030 if (initiatorContext == InitiatorContext::Worker) { 1031 1031 ASSERT(is<CachedRawResource>(resource.get())); -
trunk/Source/WebCore/page/DOMWindow.cpp
r278253 r278391 730 730 { 731 731 if (!m_performance) { 732 MonotonicTime timeOrigin = document() && document()->loader() ? document()->loader()->timing().referenceMonotonicTime() : MonotonicTime::now(); 732 auto* documentLoader = document() ? document()->loader() : nullptr; 733 auto timeOrigin = documentLoader ? documentLoader->timing().timeOrigin() : MonotonicTime::now(); 733 734 m_performance = Performance::create(document(), timeOrigin); 734 735 } -
trunk/Source/WebCore/page/Performance.cpp
r278253 r278391 229 229 } 230 230 231 void Performance::addNavigationTiming(DocumentLoader& documentLoader, Document& document, CachedResource& resource, const LoadTiming& timing, const NetworkLoadMetrics& metrics)231 void Performance::addNavigationTiming(DocumentLoader& documentLoader, Document& document, CachedResource& resource, const DocumentLoadTiming& timing, const NetworkLoadMetrics& metrics) 232 232 { 233 233 ASSERT(document.settings().performanceNavigationTimingAPIEnabled()); 234 m_navigationTiming = PerformanceNavigationTiming::create(m_timeOrigin, resource, timing, metrics, document. timing(), document.securityOrigin(), documentLoader.triggeringAction().type());234 m_navigationTiming = PerformanceNavigationTiming::create(m_timeOrigin, resource, timing, metrics, document.eventTiming(), document.securityOrigin(), documentLoader.triggeringAction().type()); 235 235 queueEntry(*m_navigationTiming); 236 236 } -
trunk/Source/WebCore/page/Performance.h
r278253 r278391 51 51 class CachedResource; 52 52 class Document; 53 class DocumentLoadTiming; 53 54 class DocumentLoader; 54 class LoadTiming;55 55 class NetworkLoadMetrics; 56 56 class PerformanceUserTiming; … … 96 96 void clearMeasures(const String& measureName); 97 97 98 void addNavigationTiming(DocumentLoader&, Document&, CachedResource&, const LoadTiming&, const NetworkLoadMetrics&);98 void addNavigationTiming(DocumentLoader&, Document&, CachedResource&, const DocumentLoadTiming&, const NetworkLoadMetrics&); 99 99 void addResourceTiming(ResourceTiming&&); 100 100 -
trunk/Source/WebCore/page/PerformanceNavigation.cpp
r262683 r278391 75 75 return 0; 76 76 77 LoadTiming& timing = loader->timing();78 if ( timing.hasCrossOriginRedirect())77 auto* metrics = loader->response().deprecatedNetworkLoadMetricsOrNull(); 78 if (!metrics) 79 79 return 0; 80 80 81 return timing.redirectCount(); 81 if (metrics->hasCrossOriginRedirect) 82 return 0; 83 84 return metrics->redirectCount; 82 85 } 83 86 -
trunk/Source/WebCore/page/PerformanceNavigationTiming.cpp
r278253 r278391 51 51 } 52 52 53 PerformanceNavigationTiming::PerformanceNavigationTiming(MonotonicTime timeOrigin, CachedResource& resource, const LoadTiming& loadTiming, const NetworkLoadMetrics& metrics, const DocumentTiming& documentTiming, const SecurityOrigin& origin, WebCore::NavigationType navigationType) 54 : PerformanceResourceTiming(timeOrigin, ResourceTiming::fromLoad(resource, resource.response().url(), "navigation"_s, loadTiming, metrics, origin)) 55 , m_documentTiming(documentTiming) 53 PerformanceNavigationTiming::PerformanceNavigationTiming(MonotonicTime timeOrigin, CachedResource& resource, const DocumentLoadTiming& documentLoadTiming, const NetworkLoadMetrics& metrics, const DocumentEventTiming& documentEventTiming, const SecurityOrigin& origin, WebCore::NavigationType navigationType) 54 : PerformanceResourceTiming(timeOrigin, ResourceTiming::fromLoad(resource, resource.response().url(), "navigation"_s, documentLoadTiming, metrics, origin)) 55 , m_documentEventTiming(documentEventTiming) 56 , m_documentLoadTiming(documentLoadTiming) 56 57 , m_navigationType(toPerformanceNavigationTimingNavigationType(navigationType)) { } 57 58 58 59 PerformanceNavigationTiming::~PerformanceNavigationTiming() = default; 59 60 60 double PerformanceNavigationTiming::millisecondsSinceOrigin(MonotonicTime time , std::optional<MonotonicTime> timeOrigin) const61 double PerformanceNavigationTiming::millisecondsSinceOrigin(MonotonicTime time) const 61 62 { 62 63 if (!time) 63 64 return 0; 64 return Performance::reduceTimeResolution(time - (timeOrigin ? *timeOrigin : m_timeOrigin)).milliseconds();65 return Performance::reduceTimeResolution(time - m_timeOrigin).milliseconds(); 65 66 } 66 67 … … 69 70 // https://www.w3.org/TR/navigation-timing-2/#dfn-same-origin-check 70 71 return !m_resourceTiming.allowTimingDetails() 71 || m_resourceTiming. loadTiming().hasCrossOriginRedirect()72 || !m_ resourceTiming.loadTiming().hasSameOriginAsPreviousDocument();72 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect 73 || !m_documentLoadTiming.hasSameOriginAsPreviousDocument(); 73 74 } 74 75 … … 77 78 if (sameOriginCheckFails()) 78 79 return 0.0; 79 return millisecondsSinceOrigin(m_ resourceTiming.loadTiming().unloadEventStart());80 return millisecondsSinceOrigin(m_documentLoadTiming.unloadEventStart()); 80 81 } 81 82 … … 84 85 if (sameOriginCheckFails()) 85 86 return 0.0; 86 return millisecondsSinceOrigin(m_ resourceTiming.loadTiming().unloadEventEnd());87 return millisecondsSinceOrigin(m_documentLoadTiming.unloadEventEnd()); 87 88 } 88 89 89 90 double PerformanceNavigationTiming::domInteractive() const 90 91 { 91 return millisecondsSinceOrigin(m_document Timing.domInteractive);92 return millisecondsSinceOrigin(m_documentEventTiming.domInteractive); 92 93 } 93 94 94 95 double PerformanceNavigationTiming::domContentLoadedEventStart() const 95 96 { 96 return millisecondsSinceOrigin(m_document Timing.domContentLoadedEventStart);97 return millisecondsSinceOrigin(m_documentEventTiming.domContentLoadedEventStart); 97 98 } 98 99 99 100 double PerformanceNavigationTiming::domContentLoadedEventEnd() const 100 101 { 101 return millisecondsSinceOrigin(m_document Timing.domContentLoadedEventEnd);102 return millisecondsSinceOrigin(m_documentEventTiming.domContentLoadedEventEnd); 102 103 } 103 104 104 105 double PerformanceNavigationTiming::domComplete() const 105 106 { 106 return millisecondsSinceOrigin(m_document Timing.domComplete);107 return millisecondsSinceOrigin(m_documentEventTiming.domComplete); 107 108 } 108 109 109 110 double PerformanceNavigationTiming::loadEventStart() const 110 111 { 111 return millisecondsSinceOrigin(m_ resourceTiming.loadTiming().loadEventStart());112 return millisecondsSinceOrigin(m_documentLoadTiming.loadEventStart()); 112 113 } 113 114 114 115 double PerformanceNavigationTiming::loadEventEnd() const 115 116 { 116 return millisecondsSinceOrigin(m_ resourceTiming.loadTiming().loadEventEnd());117 return millisecondsSinceOrigin(m_documentLoadTiming.loadEventEnd()); 117 118 } 118 119 … … 127 128 return 0; 128 129 129 if (m_resourceTiming. loadTiming().hasCrossOriginRedirect())130 if (m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 130 131 return 0; 131 132 132 return m_resourceTiming. loadTiming().redirectCount();133 return m_resourceTiming.networkLoadMetrics().redirectCount; 133 134 } 134 135 -
trunk/Source/WebCore/page/PerformanceNavigationTiming.h
r278253 r278391 26 26 #pragma once 27 27 28 #include "DocumentTiming.h" 28 #include "DocumentEventTiming.h" 29 #include "DocumentLoadTiming.h" 29 30 #include "PerformanceResourceTiming.h" 30 31 #include <wtf/MonotonicTime.h> … … 35 36 36 37 class CachedResource; 37 class LoadTiming;38 38 class NetworkLoadMetrics; 39 39 class SecurityOrigin; … … 70 70 71 71 private: 72 PerformanceNavigationTiming(MonotonicTime timeOrigin, CachedResource&, const LoadTiming&, const NetworkLoadMetrics&, const DocumentTiming&, const SecurityOrigin&, WebCore::NavigationType);72 PerformanceNavigationTiming(MonotonicTime timeOrigin, CachedResource&, const DocumentLoadTiming&, const NetworkLoadMetrics&, const DocumentEventTiming&, const SecurityOrigin&, WebCore::NavigationType); 73 73 74 double millisecondsSinceOrigin(MonotonicTime , std::optional<MonotonicTime> timeOrigin = std::nullopt) const;74 double millisecondsSinceOrigin(MonotonicTime) const; 75 75 bool sameOriginCheckFails() const; 76 76 77 DocumentTiming m_documentTiming; 77 DocumentEventTiming m_documentEventTiming; 78 DocumentLoadTiming m_documentLoadTiming; 78 79 NavigationType m_navigationType; 79 80 }; -
trunk/Source/WebCore/page/PerformanceResourceTiming.cpp
r277767 r278391 35 35 36 36 #include "Document.h" 37 #include "DocumentLoadTiming.h" 37 38 #include "DocumentLoader.h" 38 #include "LoadTiming.h"39 39 #include "PerformanceServerTiming.h" 40 40 #include "ResourceResponse.h" … … 44 44 namespace WebCore { 45 45 46 static double monotonicTimeToDOMHighResTimeStamp(MonotonicTime timeOrigin, MonotonicTime timeStamp) 47 { 48 ASSERT(timeStamp.secondsSinceEpoch().seconds() >= 0); 49 if (!timeStamp || !timeOrigin) 50 return 0; 51 52 Seconds seconds = timeStamp - timeOrigin; 53 return Performance::reduceTimeResolution(seconds).milliseconds(); 46 static double networkLoadTimeToDOMHighResTimeStamp(MonotonicTime timeOrigin, MonotonicTime timeStamp) 47 { 48 if (!timeStamp) 49 return 0.0; 50 ASSERT(timeOrigin); 51 return Performance::reduceTimeResolution(timeStamp - timeOrigin).milliseconds(); 52 } 53 54 static double fetchStart(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming) 55 { 56 if (auto fetchStart = resourceTiming.networkLoadMetrics().fetchStart) 57 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, fetchStart); 58 59 // fetchStart is a required property. 60 auto startTime = resourceTiming.resourceLoadTiming().startTime(); 61 ASSERT(startTime); 62 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, startTime); 54 63 } 55 64 56 65 static double entryStartTime(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming) 57 66 { 58 if (!resourceTiming.allowTimingDetails()) 59 return monotonicTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.loadTiming().fetchStart()); 60 61 return monotonicTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.loadTiming().startTime()); 67 if (!resourceTiming.allowTimingDetails() 68 || resourceTiming.networkLoadMetrics().hasCrossOriginRedirect 69 || !resourceTiming.networkLoadMetrics().redirectCount) 70 return fetchStart(timeOrigin, resourceTiming); 71 72 if (resourceTiming.networkLoadMetrics().redirectStart) 73 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.networkLoadMetrics().redirectStart); 74 75 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.resourceLoadTiming().startTime()); 62 76 } 63 77 … … 67 81 return entryStartTime(timeOrigin, resourceTiming); 68 82 69 if (resourceTiming.networkLoadMetrics().isComplete()) { 70 Seconds endTime = (resourceTiming.loadTiming().fetchStart() + resourceTiming.networkLoadMetrics().responseEnd) - timeOrigin; 71 return Performance::reduceTimeResolution(endTime).milliseconds(); 72 } 73 74 return monotonicTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.loadTiming().responseEnd()); 83 if (resourceTiming.networkLoadMetrics().responseEnd) 84 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.networkLoadMetrics().responseEnd); 85 86 return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.resourceLoadTiming().endTime()); 75 87 } 76 88 … … 103 115 double PerformanceResourceTiming::redirectStart() const 104 116 { 105 if (!m_resourceTiming.allowTimingDetails()) 106 return 0.0; 107 108 return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.loadTiming().redirectStart()); 117 if (!m_resourceTiming.allowTimingDetails() 118 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 119 return 0.0; 120 121 if (!m_resourceTiming.networkLoadMetrics().redirectCount) 122 return 0.0; 123 124 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().redirectStart); 109 125 } 110 126 111 127 double PerformanceResourceTiming::redirectEnd() const 112 128 { 113 if (!m_resourceTiming.allowTimingDetails()) 114 return 0.0; 115 116 return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.loadTiming().redirectEnd()); 129 if (!m_resourceTiming.allowTimingDetails() 130 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 131 return 0.0; 132 133 if (!m_resourceTiming.networkLoadMetrics().redirectCount) 134 return 0.0; 135 136 // These two times are so close to each other that we don't record two timestamps. 137 // See https://www.w3.org/TR/resource-timing-2/#attribute-descriptions 138 return fetchStart(); 117 139 } 118 140 119 141 double PerformanceResourceTiming::fetchStart() const 120 142 { 121 // fetchStart is a required property. 122 ASSERT(m_resourceTiming.loadTiming().fetchStart()); 123 124 return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.loadTiming().fetchStart()); 143 return WebCore::fetchStart(m_timeOrigin, m_resourceTiming); 125 144 } 126 145 127 146 double PerformanceResourceTiming::domainLookupStart() const 128 147 { 129 if (!m_resourceTiming.allowTimingDetails()) 130 return 0.0; 131 132 if (m_resourceTiming.networkLoadMetrics().domainLookupStart <= 0_ms) 148 if (!m_resourceTiming.allowTimingDetails() 149 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 150 return 0.0; 151 152 if (!m_resourceTiming.networkLoadMetrics().domainLookupStart) 133 153 return fetchStart(); 134 154 135 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().domainLookupStart);155 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupStart); 136 156 } 137 157 138 158 double PerformanceResourceTiming::domainLookupEnd() const 139 159 { 140 if (!m_resourceTiming.allowTimingDetails()) 141 return 0.0; 142 143 if (m_resourceTiming.networkLoadMetrics().domainLookupEnd <= 0_ms) 160 if (!m_resourceTiming.allowTimingDetails() 161 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 162 return 0.0; 163 164 if (!m_resourceTiming.networkLoadMetrics().domainLookupEnd) 144 165 return domainLookupStart(); 145 166 146 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().domainLookupEnd);167 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupEnd); 147 168 } 148 169 149 170 double PerformanceResourceTiming::connectStart() const 150 171 { 151 if (!m_resourceTiming.allowTimingDetails()) 152 return 0.0; 153 154 if (m_resourceTiming.networkLoadMetrics().connectStart <= 0_ms) 172 if (!m_resourceTiming.allowTimingDetails() 173 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 174 return 0.0; 175 176 if (!m_resourceTiming.networkLoadMetrics().connectStart) 155 177 return domainLookupEnd(); 156 178 157 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().connectStart);179 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectStart); 158 180 } 159 181 160 182 double PerformanceResourceTiming::connectEnd() const 161 183 { 162 if (!m_resourceTiming.allowTimingDetails()) 163 return 0.0; 164 165 if (m_resourceTiming.networkLoadMetrics().connectEnd <= 0_ms) 184 if (!m_resourceTiming.allowTimingDetails() 185 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 186 return 0.0; 187 188 if (!m_resourceTiming.networkLoadMetrics().connectEnd) 166 189 return connectStart(); 167 190 168 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().connectEnd);191 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectEnd); 169 192 } 170 193 171 194 double PerformanceResourceTiming::secureConnectionStart() const 172 195 { 173 if (!m_resourceTiming.allowTimingDetails()) 196 if (!m_resourceTiming.allowTimingDetails() 197 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 174 198 return 0.0; 175 199 … … 177 201 return fetchStart(); 178 202 179 if ( m_resourceTiming.networkLoadMetrics().secureConnectionStart <= 0_ms)180 return 0.0; 181 182 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().secureConnectionStart);203 if (!m_resourceTiming.networkLoadMetrics().secureConnectionStart) 204 return 0.0; 205 206 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().secureConnectionStart); 183 207 } 184 208 185 209 double PerformanceResourceTiming::requestStart() const 186 210 { 187 if (!m_resourceTiming.allowTimingDetails()) 211 if (!m_resourceTiming.allowTimingDetails() 212 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 188 213 return 0.0; 189 214 190 215 // requestStart is 0 when a network request is not made. 191 if ( m_resourceTiming.networkLoadMetrics().requestStart <= 0_ms)216 if (!m_resourceTiming.networkLoadMetrics().requestStart) 192 217 return connectEnd(); 193 218 194 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().requestStart);219 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().requestStart); 195 220 } 196 221 197 222 double PerformanceResourceTiming::responseStart() const 198 223 { 199 if (!m_resourceTiming.allowTimingDetails()) 224 if (!m_resourceTiming.allowTimingDetails() 225 || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect) 200 226 return 0.0; 201 227 202 228 // responseStart is 0 when a network request is not made. 203 if ( m_resourceTiming.networkLoadMetrics().responseStart <= 0_ms)229 if (!m_resourceTiming.networkLoadMetrics().responseStart) 204 230 return requestStart(); 205 231 206 return networkLoadTimeToDOMHighResTimeStamp(m_ resourceTiming.networkLoadMetrics().responseStart);232 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseStart); 207 233 } 208 234 … … 210 236 { 211 237 // responseEnd is a required property. 212 ASSERT(m_resourceTiming.networkLoadMetrics().isComplete() || m_resourceTiming. loadTiming().responseEnd());238 ASSERT(m_resourceTiming.networkLoadMetrics().isComplete() || m_resourceTiming.resourceLoadTiming().endTime()); 213 239 214 240 if (m_resourceTiming.networkLoadMetrics().isComplete()) { 241 if (m_resourceTiming.networkLoadMetrics().responseEnd) 242 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseEnd); 243 215 244 // responseEnd is 0 when a network request is not made. 216 245 // This should mean all other properties are empty. 217 if (m_resourceTiming.networkLoadMetrics().responseEnd <= 0_ms) { 218 ASSERT(m_resourceTiming.networkLoadMetrics().responseStart <= 0_ms); 219 ASSERT(m_resourceTiming.networkLoadMetrics().requestStart <= 0_ms); 220 ASSERT(m_resourceTiming.networkLoadMetrics().requestStart <= 0_ms); 221 ASSERT(m_resourceTiming.networkLoadMetrics().secureConnectionStart <= 0_ms); 222 ASSERT(m_resourceTiming.networkLoadMetrics().connectEnd <= 0_ms); 223 ASSERT(m_resourceTiming.networkLoadMetrics().connectStart <= 0_ms); 224 ASSERT(m_resourceTiming.networkLoadMetrics().domainLookupEnd <= 0_ms); 225 ASSERT(m_resourceTiming.networkLoadMetrics().domainLookupStart <= 0_ms); 226 return responseStart(); 227 } 228 229 return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().responseEnd); 246 ASSERT(!m_resourceTiming.networkLoadMetrics().responseStart); 247 ASSERT(!m_resourceTiming.networkLoadMetrics().requestStart); 248 ASSERT(!m_resourceTiming.networkLoadMetrics().requestStart); 249 ASSERT(!m_resourceTiming.networkLoadMetrics().secureConnectionStart); 250 ASSERT(!m_resourceTiming.networkLoadMetrics().connectEnd); 251 ASSERT(!m_resourceTiming.networkLoadMetrics().connectStart); 252 ASSERT(!m_resourceTiming.networkLoadMetrics().domainLookupEnd); 253 ASSERT(!m_resourceTiming.networkLoadMetrics().domainLookupStart); 230 254 } 231 255 232 return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.loadTiming().responseEnd()); 233 } 234 235 double PerformanceResourceTiming::networkLoadTimeToDOMHighResTimeStamp(Seconds delta) const 236 { 237 ASSERT(delta); 238 Seconds final = (m_resourceTiming.loadTiming().fetchStart() + delta) - m_timeOrigin; 239 return Performance::reduceTimeResolution(final).milliseconds(); 256 return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.resourceLoadTiming().endTime()); 240 257 } 241 258 -
trunk/Source/WebCore/page/PerformanceResourceTiming.h
r277767 r278391 32 32 #pragma once 33 33 34 #include "LoadTiming.h"35 34 #include "NetworkLoadMetrics.h" 36 35 #include "PerformanceEntry.h" … … 73 72 ~PerformanceResourceTiming(); 74 73 75 double networkLoadTimeToDOMHighResTimeStamp(Seconds) const;76 77 74 MonotonicTime m_timeOrigin; 78 75 const ResourceTiming m_resourceTiming; -
trunk/Source/WebCore/page/PerformanceTiming.cpp
r256632 r278391 33 33 34 34 #include "Document.h" 35 #include "DocumentEventTiming.h" 36 #include "DocumentLoadTiming.h" 35 37 #include "DocumentLoader.h" 36 #include "DocumentTiming.h"37 38 #include "Frame.h" 38 39 #include "FrameLoader.h" 39 #include "LoadTiming.h"40 40 #include "NetworkLoadMetrics.h" 41 41 #include "Performance.h" … … 51 51 unsigned long long PerformanceTiming::navigationStart() const 52 52 { 53 LoadTiming* timing = loadTiming();53 auto* timing = documentLoadTiming(); 54 54 if (!timing) 55 55 return 0; … … 60 60 unsigned long long PerformanceTiming::unloadEventStart() const 61 61 { 62 LoadTiming* timing = loadTiming(); 63 if (!timing) 64 return 0; 65 66 if (timing->hasCrossOriginRedirect() || !timing->hasSameOriginAsPreviousDocument()) 62 auto* timing = documentLoadTiming(); 63 if (!timing) 64 return 0; 65 66 auto* metrics = networkLoadMetrics(); 67 if (!metrics) 68 return 0; 69 70 if (metrics->hasCrossOriginRedirect || !timing->hasSameOriginAsPreviousDocument()) 67 71 return 0; 68 72 … … 72 76 unsigned long long PerformanceTiming::unloadEventEnd() const 73 77 { 74 LoadTiming* timing = loadTiming(); 75 if (!timing) 76 return 0; 77 78 if (timing->hasCrossOriginRedirect() || !timing->hasSameOriginAsPreviousDocument()) 78 auto* timing = documentLoadTiming(); 79 if (!timing) 80 return 0; 81 82 auto* metrics = networkLoadMetrics(); 83 if (!metrics) 84 return 0; 85 86 if (metrics->hasCrossOriginRedirect || !timing->hasSameOriginAsPreviousDocument()) 79 87 return 0; 80 88 … … 84 92 unsigned long long PerformanceTiming::redirectStart() const 85 93 { 86 LoadTiming* timing = loadTiming(); 87 if (!timing) 88 return 0; 89 90 if (timing->hasCrossOriginRedirect()) 91 return 0; 92 93 return monotonicTimeToIntegerMilliseconds(timing->redirectStart()); 94 auto* metrics = networkLoadMetrics(); 95 if (!metrics 96 || metrics->hasCrossOriginRedirect 97 || !metrics->redirectCount) 98 return 0; 99 100 return monotonicTimeToIntegerMilliseconds(metrics->redirectStart); 94 101 } 95 102 96 103 unsigned long long PerformanceTiming::redirectEnd() const 97 104 { 98 LoadTiming* timing = loadTiming(); 99 if (!timing) 100 return 0; 101 102 if (timing->hasCrossOriginRedirect()) 103 return 0; 104 105 return monotonicTimeToIntegerMilliseconds(timing->redirectEnd()); 105 auto* metrics = networkLoadMetrics(); 106 if (!metrics 107 || metrics->hasCrossOriginRedirect 108 || !metrics->redirectCount) 109 return 0; 110 111 return monotonicTimeToIntegerMilliseconds(metrics->fetchStart); 106 112 } 107 113 108 114 unsigned long long PerformanceTiming::fetchStart() const 109 115 { 110 LoadTiming* timing = loadTiming();111 if (! timing)112 return 0; 113 114 return monotonicTimeToIntegerMilliseconds( timing->fetchStart());116 auto* metrics = networkLoadMetrics(); 117 if (!metrics) 118 return 0; 119 120 return monotonicTimeToIntegerMilliseconds(metrics->fetchStart); 115 121 } 116 122 117 123 unsigned long long PerformanceTiming::domainLookupStart() const 118 124 { 119 DocumentLoader* loader = documentLoader();120 if (! loader)125 auto* metrics = networkLoadMetrics(); 126 if (!metrics || !metrics->domainLookupStart) 121 127 return fetchStart(); 122 123 const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull(); 124 125 // This will be -1 when a DNS request is not performed. 126 // Rather than exposing a special value that indicates no DNS, we "backfill" with fetchStart. 127 if (!timing || timing->domainLookupStart < 0_ms) 128 return fetchStart(); 129 130 return resourceLoadTimeRelativeToFetchStart(timing->domainLookupStart); 128 129 return monotonicTimeToIntegerMilliseconds(metrics->domainLookupStart); 131 130 } 132 131 133 132 unsigned long long PerformanceTiming::domainLookupEnd() const 134 133 { 135 DocumentLoader* loader = documentLoader();136 if (! loader)134 auto* metrics = networkLoadMetrics(); 135 if (!metrics || !metrics->domainLookupEnd) 137 136 return domainLookupStart(); 138 139 const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull(); 140 141 // This will be -1 when a DNS request is not performed. 142 // Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart. 143 if (!timing || timing->domainLookupEnd < 0_ms) 144 return domainLookupStart(); 145 146 return resourceLoadTimeRelativeToFetchStart(timing->domainLookupEnd); 137 138 return monotonicTimeToIntegerMilliseconds(metrics->domainLookupEnd); 147 139 } 148 140 149 141 unsigned long long PerformanceTiming::connectStart() const 150 142 { 151 DocumentLoader* loader = documentLoader(); 152 if (!loader) 143 auto* metrics = networkLoadMetrics(); 144 if (!metrics || !metrics->connectStart 145 || metrics->domainLookupEnd.secondsSinceEpoch() > metrics->connectStart.secondsSinceEpoch()) 153 146 return domainLookupEnd(); 154 147 155 const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull(); 156 157 // connectStart will be -1 when a network request is not made. 158 // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd. 159 if (!timing) 160 return domainLookupEnd(); 161 Seconds connectStart = timing->connectStart; 162 if (connectStart < 0_ms) 163 return domainLookupEnd(); 164 165 // NetworkLoadMetrics's connect phase includes DNS, however Navigation Timing's 166 // connect phase should not. So if there is DNS time, trim it from the start. 167 if (timing->domainLookupEnd >= 0_ms && timing->domainLookupEnd > connectStart) 168 connectStart = timing->domainLookupEnd; 169 170 return resourceLoadTimeRelativeToFetchStart(connectStart); 148 return monotonicTimeToIntegerMilliseconds(metrics->connectStart); 171 149 } 172 150 173 151 unsigned long long PerformanceTiming::connectEnd() const 174 152 { 175 DocumentLoader* loader = documentLoader();176 if (! loader)153 auto* metrics = networkLoadMetrics(); 154 if (!metrics || !metrics->connectEnd) 177 155 return connectStart(); 178 156 179 const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull(); 180 181 // connectEnd will be -1 when a network request is not made. 182 // Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart. 183 if (!timing || timing->connectEnd < 0_ms) 184 return connectStart(); 185 186 return resourceLoadTimeRelativeToFetchStart(timing->connectEnd); 157 return monotonicTimeToIntegerMilliseconds(metrics->connectEnd); 187 158 } 188 159 189 160 unsigned long long PerformanceTiming::secureConnectionStart() const 190 161 { 191 DocumentLoader* loader = documentLoader(); 192 if (!loader) 193 return 0; 194 195 const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull(); 196 197 if (!timing || timing->secureConnectionStart < 0_ms) 198 return 0; 199 200 return resourceLoadTimeRelativeToFetchStart(timing->secureConnectionStart); 162 auto* metrics = networkLoadMetrics(); 163 if (!metrics) 164 return connectEnd(); 165 166 if (!metrics->secureConnectionStart 167 || metrics->secureConnectionStart == reusedTLSConnectionSentinel) 168 return 0; 169 170 return monotonicTimeToIntegerMilliseconds(metrics->secureConnectionStart); 201 171 } 202 172 203 173 unsigned long long PerformanceTiming::requestStart() const 204 174 { 205 DocumentLoader* loader = documentLoader();206 if (! loader)175 auto* metrics = networkLoadMetrics(); 176 if (!metrics || !metrics->requestStart) 207 177 return connectEnd(); 208 178 209 Seconds requestStart = 0_ms; 210 if (const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull()) 211 requestStart = timing->requestStart; 212 213 ASSERT(requestStart >= 0_ms); 214 return resourceLoadTimeRelativeToFetchStart(requestStart); 179 return monotonicTimeToIntegerMilliseconds(metrics->requestStart); 215 180 } 216 181 217 182 unsigned long long PerformanceTiming::responseStart() const 218 183 { 219 DocumentLoader* loader = documentLoader();220 if (! loader)184 auto* metrics = networkLoadMetrics(); 185 if (!metrics || !metrics->responseStart) 221 186 return requestStart(); 222 187 223 Seconds responseStart = 0_ms; 224 if (const NetworkLoadMetrics* timing = loader->response().deprecatedNetworkLoadMetricsOrNull()) 225 responseStart = timing->responseStart; 226 227 ASSERT(responseStart >= 0_ms); 228 return resourceLoadTimeRelativeToFetchStart(responseStart); 188 return monotonicTimeToIntegerMilliseconds(metrics->responseStart); 229 189 } 230 190 231 191 unsigned long long PerformanceTiming::responseEnd() const 232 192 { 233 LoadTiming* timing = loadTiming();234 if (! timing)235 return 0;236 237 return monotonicTimeToIntegerMilliseconds( timing->responseEnd());193 auto* metrics = networkLoadMetrics(); 194 if (!metrics || !metrics->responseEnd) 195 return responseStart(); 196 197 return monotonicTimeToIntegerMilliseconds(metrics->responseEnd); 238 198 } 239 199 240 200 unsigned long long PerformanceTiming::domLoading() const 241 201 { 242 const DocumentTiming* timing = documentTiming();202 auto* timing = documentEventTiming(); 243 203 if (!timing) 244 204 return fetchStart(); … … 249 209 unsigned long long PerformanceTiming::domInteractive() const 250 210 { 251 const DocumentTiming* timing = documentTiming();211 auto* timing = documentEventTiming(); 252 212 if (!timing) 253 213 return 0; … … 258 218 unsigned long long PerformanceTiming::domContentLoadedEventStart() const 259 219 { 260 const DocumentTiming* timing = documentTiming();220 auto* timing = documentEventTiming(); 261 221 if (!timing) 262 222 return 0; … … 267 227 unsigned long long PerformanceTiming::domContentLoadedEventEnd() const 268 228 { 269 const DocumentTiming* timing = documentTiming();229 auto* timing = documentEventTiming(); 270 230 if (!timing) 271 231 return 0; … … 276 236 unsigned long long PerformanceTiming::domComplete() const 277 237 { 278 const DocumentTiming* timing = documentTiming();238 auto* timing = documentEventTiming(); 279 239 if (!timing) 280 240 return 0; … … 285 245 unsigned long long PerformanceTiming::loadEventStart() const 286 246 { 287 LoadTiming* timing = loadTiming();247 auto* timing = documentLoadTiming(); 288 248 if (!timing) 289 249 return 0; … … 294 254 unsigned long long PerformanceTiming::loadEventEnd() const 295 255 { 296 LoadTiming* timing = loadTiming();256 auto* timing = documentLoadTiming(); 297 257 if (!timing) 298 258 return 0; … … 301 261 } 302 262 303 DocumentLoader* PerformanceTiming::documentLoader() const263 const DocumentLoader* PerformanceTiming::documentLoader() const 304 264 { 305 265 auto* frame = this->frame(); … … 310 270 } 311 271 312 const Document Timing* PerformanceTiming::documentTiming() const272 const DocumentEventTiming* PerformanceTiming::documentEventTiming() const 313 273 { 314 274 auto* frame = this->frame(); … … 316 276 return nullptr; 317 277 318 Document* document = frame->document();278 auto* document = frame->document(); 319 279 if (!document) 320 280 return nullptr; 321 281 322 return &document-> timing();323 } 324 325 LoadTiming* PerformanceTiming::loadTiming() const326 { 327 DocumentLoader* loader = documentLoader();282 return &document->eventTiming(); 283 } 284 285 const DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const 286 { 287 auto* loader = documentLoader(); 328 288 if (!loader) 329 289 return nullptr; … … 332 292 } 333 293 334 unsigned long long PerformanceTiming::resourceLoadTimeRelativeToFetchStart(Seconds delta) const 335 { 336 ASSERT(delta >= 0_ms); 337 338 LoadTiming* timing = loadTiming(); 339 if (!timing) 340 return 0; 341 342 WallTime fetchStart = timing->monotonicTimeToPseudoWallTime(timing->fetchStart()); 343 WallTime combined = fetchStart + delta; 344 Seconds reduced = Performance::reduceTimeResolution(combined.secondsSinceEpoch()); 294 const NetworkLoadMetrics* PerformanceTiming::networkLoadMetrics() const 295 { 296 auto* loader = documentLoader(); 297 if (!loader) 298 return nullptr; 299 return loader->response().deprecatedNetworkLoadMetricsOrNull(); 300 } 301 302 unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(MonotonicTime timeStamp) const 303 { 304 ASSERT(timeStamp.secondsSinceEpoch().seconds() >= 0); 305 if (!timeStamp) 306 return 0; 307 Seconds reduced = Performance::reduceTimeResolution(timeStamp.approximateWallTime().secondsSinceEpoch()); 345 308 return static_cast<unsigned long long>(reduced.milliseconds()); 346 309 } 347 310 348 unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(MonotonicTime timeStamp) const349 {350 ASSERT(timeStamp.secondsSinceEpoch().seconds() >= 0);351 352 LoadTiming* timing = loadTiming();353 if (!timing)354 return 0;355 356 WallTime wallTime = timing->monotonicTimeToPseudoWallTime(timeStamp);357 Seconds reduced = Performance::reduceTimeResolution(wallTime.secondsSinceEpoch());358 return static_cast<unsigned long long>(reduced.milliseconds());359 }360 361 311 } // namespace WebCore -
trunk/Source/WebCore/page/PerformanceTiming.h
r236917 r278391 39 39 40 40 class DocumentLoader; 41 class DocumentLoadTiming; 41 42 class LoadTiming; 42 struct DocumentTiming; 43 class NetworkLoadMetrics; 44 45 struct DocumentEventTiming; 43 46 44 47 class PerformanceTiming : public RefCounted<PerformanceTiming>, public DOMWindowProperty { … … 71 74 explicit PerformanceTiming(DOMWindow*); 72 75 73 const Document Timing* documentTiming() const;74 DocumentLoader* documentLoader() const;75 LoadTiming* loadTiming() const;76 unsigned long long resourceLoadTimeRelativeToFetchStart(Seconds) const;76 const DocumentEventTiming* documentEventTiming() const; 77 const DocumentLoader* documentLoader() const; 78 const DocumentLoadTiming* documentLoadTiming() const; 79 const NetworkLoadMetrics* networkLoadMetrics() const; 77 80 unsigned long long monotonicTimeToIntegerMilliseconds(MonotonicTime) const; 78 81 }; -
trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h
r278340 r278391 1 1 /* 2 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 3 * Copyright (C) 2014-20 17Apple, Inc. All Rights Reserved.3 * Copyright (C) 2014-2021 Apple, Inc. All Rights Reserved. 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "HTTPHeaderMap.h" 30 30 #include <wtf/Box.h> 31 #include <wtf/ Seconds.h>31 #include <wtf/MonotonicTime.h> 32 32 #include <wtf/persistence/PersistentCoder.h> 33 33 #include <wtf/text/WTFString.h> … … 48 48 OBJC_CLASS NSURLConnection; 49 49 OBJC_CLASS NSURLResponse; 50 OBJC_CLASS NSURLSessionTask TransactionMetrics;50 OBJC_CLASS NSURLSessionTaskMetrics; 51 51 #endif 52 52 53 53 namespace WebCore { 54 55 class ResourceHandle; 54 56 55 57 enum class NetworkLoadPriority : uint8_t { … … 62 64 NETWORK_LOAD_METRICS_ADDITIONS_1; 63 65 64 constexpr Seconds reusedTLSConnectionSentinel { -2};66 constexpr MonotonicTime reusedTLSConnectionSentinel { MonotonicTime::fromRawSeconds(-1) }; 65 67 66 68 class NetworkLoadMetricsWithoutNonTimingData { 67 69 WTF_MAKE_FAST_ALLOCATED(NetworkLoadMetricsWithoutNonTimingData); 68 70 public: 69 NetworkLoadMetricsWithoutNonTimingData() = default;70 71 71 bool isComplete() const { return complete; } 72 72 void markComplete() { complete = true; } 73 73 74 Seconds fetchStart; 75 76 // These should be treated as deltas to fetchStart. 77 // They should be in ascending order as listed here. 78 Seconds domainLookupStart { -1 }; // -1 if no DNS. 79 Seconds domainLookupEnd { -1 }; // -1 if no DNS. 80 Seconds connectStart { -1 }; // -1 if reused connection. 81 Seconds secureConnectionStart { -1 }; // -1 if no secure connection. 82 Seconds connectEnd { -1 }; // -1 if reused connection. 83 Seconds requestStart; 84 Seconds responseStart; 85 Seconds responseEnd; 86 74 // https://www.w3.org/TR/resource-timing-2/#attribute-descriptions 75 MonotonicTime redirectStart; 76 MonotonicTime fetchStart; 77 MonotonicTime domainLookupStart; 78 MonotonicTime domainLookupEnd; 79 MonotonicTime connectStart; 80 MonotonicTime secureConnectionStart; 81 MonotonicTime connectEnd; 82 MonotonicTime requestStart; 83 MonotonicTime responseStart; 84 MonotonicTime responseEnd; 85 87 86 // ALPN Protocol ID: https://w3c.github.io/resource-timing/#bib-RFC7301 88 87 String protocol; 88 89 uint16_t redirectCount { 0 }; 90 91 // FIXME: These could all be made bit fields. 89 92 bool complete { false }; 90 93 bool cellular { false }; … … 93 96 bool multipath { false }; 94 97 bool isReusedConnection { false }; 98 bool hasCrossOriginRedirect { false }; 95 99 }; 96 100 … … 106 110 NetworkLoadMetrics copy; 107 111 112 copy.redirectStart = redirectStart; 108 113 copy.fetchStart = fetchStart; 109 114 … … 118 123 copy.complete = complete; 119 124 copy.protocol = protocol.isolatedCopy(); 125 copy.redirectCount = redirectCount; 120 126 copy.cellular = cellular; 121 127 copy.expensive = expensive; … … 123 129 copy.multipath = multipath; 124 130 copy.isReusedConnection = isReusedConnection; 131 copy.hasCrossOriginRedirect = hasCrossOriginRedirect; 125 132 126 133 copy.remoteAddress = remoteAddress.isolatedCopy(); … … 143 150 bool operator==(const NetworkLoadMetrics& other) const 144 151 { 145 return fetchStart == other.fetchStart 152 return redirectStart == other.redirectStart 153 && fetchStart == other.fetchStart 146 154 && domainLookupStart == other.domainLookupStart 147 155 && domainLookupEnd == other.domainLookupEnd … … 158 166 && multipath == other.multipath 159 167 && isReusedConnection == other.isReusedConnection 168 && hasCrossOriginRedirect == other.hasCrossOriginRedirect 160 169 && protocol == other.protocol 170 && redirectCount == other.redirectCount 161 171 && remoteAddress == other.remoteAddress 162 172 && connectionIdentifier == other.connectionIdentifier … … 192 202 HTTPHeaderMap requestHeaders; 193 203 194 uint64_t requestHeaderBytesSent { std::numeric_limits<uint 32_t>::max() };195 uint64_t responseHeaderBytesReceived { std::numeric_limits<uint 32_t>::max() };204 uint64_t requestHeaderBytesSent { std::numeric_limits<uint64_t>::max() }; 205 uint64_t responseHeaderBytesReceived { std::numeric_limits<uint64_t>::max() }; 196 206 uint64_t requestBodyBytesSent { std::numeric_limits<uint64_t>::max() }; 197 207 uint64_t responseBodyBytesReceived { std::numeric_limits<uint64_t>::max() }; … … 200 210 201 211 #if PLATFORM(COCOA) 202 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection * );203 WEBCORE_EXPORT Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTask TransactionMetrics *incompleteMetrics);212 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *, const ResourceHandle&); 213 WEBCORE_EXPORT Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, bool hasCrossOriginRedirect); 204 214 #endif 205 215 … … 209 219 static_assert(Encoder::isIPCEncoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder"); 210 220 221 encoder << redirectStart; 211 222 encoder << fetchStart; 212 223 encoder << domainLookupStart; … … 224 235 encoder << multipath; 225 236 encoder << isReusedConnection; 237 encoder << hasCrossOriginRedirect; 226 238 encoder << protocol; 239 encoder << redirectCount; 227 240 encoder << remoteAddress; 228 241 encoder << connectionIdentifier; … … 244 257 static_assert(Decoder::isIPCDecoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder"); 245 258 246 return decoder.decode(metrics.fetchStart) 259 return decoder.decode(metrics.redirectStart) 260 && decoder.decode(metrics.fetchStart) 247 261 && decoder.decode(metrics.domainLookupStart) 248 262 && decoder.decode(metrics.domainLookupEnd) … … 259 273 && decoder.decode(metrics.multipath) 260 274 && decoder.decode(metrics.isReusedConnection) 275 && decoder.decode(metrics.hasCrossOriginRedirect) 261 276 && decoder.decode(metrics.protocol) 277 && decoder.decode(metrics.redirectCount) 262 278 && decoder.decode(metrics.remoteAddress) 263 279 && decoder.decode(metrics.connectionIdentifier) -
trunk/Source/WebCore/platform/network/ResourceHandle.cpp
r278253 r278391 204 204 d->m_currentWebChallenge.nullify(); 205 205 } 206 206 207 bool ResourceHandle::hasCrossOriginRedirect() const 208 { 209 return d->m_hasCrossOriginRedirect; 210 } 211 212 void ResourceHandle::setHasCrossOriginRedirect(bool value) 213 { 214 d->m_hasCrossOriginRedirect = value; 215 } 216 217 void ResourceHandle::incrementRedirectCount() 218 { 219 d->m_redirectCount++; 220 } 221 222 uint16_t ResourceHandle::redirectCount() const 223 { 224 return d->m_redirectCount; 225 } 226 227 MonotonicTime ResourceHandle::startTimeBeforeRedirects() const 228 { 229 return d->m_startTime; 230 } 231 232 NetworkLoadMetrics* ResourceHandle::networkLoadMetrics() 233 { 234 return d->m_networkLoadMetrics.get(); 235 } 236 237 void ResourceHandle::setNetworkLoadMetrics(Box<NetworkLoadMetrics>&& metrics) 238 { 239 d->m_networkLoadMetrics = WTFMove(metrics); 240 } 241 207 242 bool ResourceHandle::shouldContentSniff() const 208 243 { -
trunk/Source/WebCore/platform/network/ResourceHandle.h
r278253 r278391 171 171 WEBCORE_EXPORT virtual void cancel(); 172 172 173 NetworkLoadMetrics* networkLoadMetrics(); 174 void setNetworkLoadMetrics(Box<NetworkLoadMetrics>&&); 175 176 MonotonicTime startTimeBeforeRedirects() const; 177 bool hasCrossOriginRedirect() const; 178 void setHasCrossOriginRedirect(bool); 179 uint16_t redirectCount() const; 180 void incrementRedirectCount(); 181 173 182 // The client may be 0, in which case no callbacks will be made. 174 183 WEBCORE_EXPORT ResourceHandleClient* client() const; -
trunk/Source/WebCore/platform/network/ResourceHandleInternal.h
r264811 r278391 32 32 #include "ResourceRequest.h" 33 33 #include "Timer.h" 34 #include <wtf/MonotonicTime.h> 34 35 35 36 #if USE(CFURLCONNECTION) … … 125 126 126 127 bool m_cancelled { false }; 127 unsigned m_redirectCount { 0 };128 128 unsigned m_authFailureCount { 0 }; 129 129 bool m_addedCacheValidationHeaders { false }; 130 130 RefPtr<CurlRequest> m_curlRequest; 131 131 RefPtr<SynchronousLoaderMessageQueue> m_messageQueue; 132 #endif 133 Box<NetworkLoadMetrics> m_networkLoadMetrics; 132 134 MonotonicTime m_startTime; 133 #endif 135 uint16_t m_redirectCount { 0 }; 136 bool m_hasCrossOriginRedirect { false }; 134 137 135 138 #if PLATFORM(COCOA) -
trunk/Source/WebCore/platform/network/cocoa/NetworkLoadMetrics.mm
r277767 r278391 27 27 #import "NetworkLoadMetrics.h" 28 28 29 #import "ResourceHandle.h" 29 30 #import <pal/spi/cocoa/NSURLConnectionSPI.h> 30 31 31 32 namespace WebCore { 32 33 33 static Box<NetworkLoadMetrics> packageTimingData(double fetchStart, double domainLookupStart, double domainLookupEnd, double connectStart, double secureConnectionStart, double connectEnd, double requestStart, double responseStart, bool reusedTLSConnection, NSString *protocol)34 static MonotonicTime dateToMonotonicTime(NSDate *date) 34 35 { 36 if (auto interval = date.timeIntervalSince1970) 37 return WallTime::fromRawSeconds(interval).approximateMonotonicTime(); 38 return { }; 39 } 40 41 static Box<NetworkLoadMetrics> packageTimingData(MonotonicTime redirectStart, NSDate *fetchStart, NSDate *domainLookupStart, NSDate *domainLookupEnd, NSDate *connectStart, NSDate *secureConnectionStart, NSDate *connectEnd, NSDate *requestStart, NSDate *responseStart, bool reusedTLSConnection, NSString *protocol, uint16_t redirectCount, bool hasCrossOriginRedirect) 42 { 43 35 44 auto timing = Box<NetworkLoadMetrics>::create(); 36 45 37 timing->fetchStart = Seconds(fetchStart); 38 timing->domainLookupStart = Seconds(domainLookupStart <= 0 ? -1 : domainLookupStart - fetchStart); 39 timing->domainLookupEnd = Seconds(domainLookupEnd <= 0 ? -1 : domainLookupEnd - fetchStart); 40 timing->connectStart = Seconds(connectStart <= 0 ? -1 : connectStart - fetchStart); 46 timing->redirectStart = redirectStart; 47 timing->fetchStart = dateToMonotonicTime(fetchStart); 48 timing->domainLookupStart = dateToMonotonicTime(domainLookupStart); 49 timing->domainLookupEnd = dateToMonotonicTime(domainLookupEnd); 50 timing->connectStart = dateToMonotonicTime(connectStart); 41 51 if (reusedTLSConnection && [protocol isEqualToString:@"https"]) 42 52 timing->secureConnectionStart = reusedTLSConnectionSentinel; 43 53 else 44 timing->secureConnectionStart = Seconds(secureConnectionStart <= 0 ? -1 : secureConnectionStart - fetchStart); 45 timing->connectEnd = Seconds(connectEnd <= 0 ? -1 : connectEnd - fetchStart); 46 timing->requestStart = Seconds(requestStart <= 0 ? 0 : requestStart - fetchStart); 47 timing->responseStart = Seconds(responseStart <= 0 ? 0 : responseStart - fetchStart); 54 timing->secureConnectionStart = dateToMonotonicTime(secureConnectionStart); 55 timing->connectEnd = dateToMonotonicTime(connectEnd); 56 timing->requestStart = dateToMonotonicTime(requestStart); 57 timing->responseStart = dateToMonotonicTime(responseStart); 58 timing->redirectCount = redirectCount; 59 timing->hasCrossOriginRedirect = hasCrossOriginRedirect; 48 60 49 61 // NOTE: responseEnd is not populated in this code path. … … 52 64 } 53 65 54 Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTask TransactionMetrics *incompleteMetrics)66 Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, bool hasCrossOriginRedirect) 55 67 { 68 NSArray<NSURLSessionTaskTransactionMetrics *> *transactionMetrics = incompleteMetrics.transactionMetrics; 69 NSURLSessionTaskTransactionMetrics *metrics = transactionMetrics.lastObject; 56 70 return packageTimingData( 57 incompleteMetrics.fetchStartDate.timeIntervalSince1970, 58 incompleteMetrics.domainLookupStartDate.timeIntervalSince1970, 59 incompleteMetrics.domainLookupEndDate.timeIntervalSince1970, 60 incompleteMetrics.connectStartDate.timeIntervalSince1970, 61 incompleteMetrics.secureConnectionStartDate.timeIntervalSince1970, 62 incompleteMetrics.connectEndDate.timeIntervalSince1970, 63 incompleteMetrics.requestStartDate.timeIntervalSince1970, 64 incompleteMetrics.responseStartDate.timeIntervalSince1970, 65 incompleteMetrics.reusedConnection, 66 incompleteMetrics.response.URL.scheme 71 dateToMonotonicTime(transactionMetrics.firstObject.fetchStartDate), 72 metrics.fetchStartDate, 73 metrics.domainLookupStartDate, 74 metrics.domainLookupEndDate, 75 metrics.connectStartDate, 76 metrics.secureConnectionStartDate, 77 metrics.connectEndDate, 78 metrics.requestStartDate, 79 metrics.responseStartDate, 80 metrics.reusedConnection, 81 metrics.response.URL.scheme, 82 incompleteMetrics.redirectCount, 83 hasCrossOriginRedirect 67 84 ); 68 85 } 69 86 70 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *connection )87 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *connection, const ResourceHandle& handle) 71 88 { 72 89 NSDictionary *timingData = [connection _timingData]; 73 if (!timingData)74 return nullptr;75 90 76 auto timingValue = [](NSDictionary *timingData, NSString *key) { 77 if (id object = [timingData objectForKey:key]) 78 return [object doubleValue]; 79 return 0.0; 91 auto timingValue = [&](NSString *key) -> RetainPtr<NSDate> { 92 if (NSNumber *number = [timingData objectForKey:key]) { 93 if (double doubleValue = number.doubleValue) 94 return adoptNS([[NSDate alloc] initWithTimeIntervalSinceReferenceDate:doubleValue]); 95 } 96 return { }; 80 97 }; 81 98 82 return packageTimingData( 83 timingValue(timingData, @"_kCFNTimingDataFetchStart"), 84 timingValue(timingData, @"_kCFNTimingDataDomainLookupStart"), 85 timingValue(timingData, @"_kCFNTimingDataDomainLookupEnd"), 86 timingValue(timingData, @"_kCFNTimingDataConnectStart"), 87 timingValue(timingData, @"_kCFNTimingDataSecureConnectionStart"), 88 timingValue(timingData, @"_kCFNTimingDataConnectEnd"), 89 timingValue(timingData, @"_kCFNTimingDataRequestStart"), 90 timingValue(timingData, @"_kCFNTimingDataResponseStart"), 91 timingValue(timingData, @"_kCFNTimingDataConnectionReused"), 92 connection.currentRequest.URL.scheme 99 auto data = packageTimingData( 100 handle.startTimeBeforeRedirects(), 101 timingValue(@"_kCFNTimingDataFetchStart").get(), 102 timingValue(@"_kCFNTimingDataDomainLookupStart").get(), 103 timingValue(@"_kCFNTimingDataDomainLookupEnd").get(), 104 timingValue(@"_kCFNTimingDataConnectStart").get(), 105 timingValue(@"_kCFNTimingDataSecureConnectionStart").get(), 106 timingValue(@"_kCFNTimingDataConnectEnd").get(), 107 timingValue(@"_kCFNTimingDataRequestStart").get(), 108 timingValue(@"_kCFNTimingDataResponseStart").get(), 109 timingValue(@"_kCFNTimingDataConnectionReused").get(), 110 connection.currentRequest.URL.scheme, 111 handle.redirectCount(), 112 handle.hasCrossOriginRedirect() 93 113 ); 114 115 if (!data->fetchStart) 116 data->fetchStart = data->redirectStart; 117 118 return data; 94 119 } 95 120 -
trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm
r277958 r278391 51 51 NS_ASSUME_NONNULL_BEGIN 52 52 53 static NSDate * __nullable networkLoadMetricsDate( Seconds fetchStart, Seconds delta)54 { 55 if (! fetchStart.value())53 static NSDate * __nullable networkLoadMetricsDate(MonotonicTime time) 54 { 55 if (!time) 56 56 return nil; 57 if (delta.value() == -1) 57 NSTimeInterval value = time.approximateWallTime().secondsSinceEpoch().seconds(); 58 if (value <= 0) 58 59 return nil; 59 return [NSDate dateWithTimeIntervalSince1970: fetchStart.value() + delta.value()];60 return [NSDate dateWithTimeIntervalSince1970:value]; 60 61 } 61 62 … … 95 96 - (nullable NSDate *)fetchStartDate 96 97 { 97 return networkLoadMetricsDate(_metrics.fetchStart , Seconds(0));98 return networkLoadMetricsDate(_metrics.fetchStart); 98 99 } 99 100 … … 101 102 - (nullable NSDate *)domainLookupStartDate 102 103 { 103 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.domainLookupStart);104 return networkLoadMetricsDate(_metrics.domainLookupStart); 104 105 } 105 106 … … 107 108 - (nullable NSDate *)domainLookupEndDate 108 109 { 109 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.domainLookupEnd);110 return networkLoadMetricsDate(_metrics.domainLookupEnd); 110 111 } 111 112 … … 113 114 - (nullable NSDate *)connectStartDate 114 115 { 115 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.connectStart);116 return networkLoadMetricsDate(_metrics.connectStart); 116 117 } 117 118 … … 119 120 - (nullable NSDate *)secureConnectionStartDate 120 121 { 121 return networkLoadMetricsDate(_metrics.fetchStart, _metrics.secureConnectionStart); 122 if (_metrics.secureConnectionStart == reusedTLSConnectionSentinel) 123 return nil; 124 return networkLoadMetricsDate(_metrics.secureConnectionStart); 122 125 } 123 126 … … 125 128 - (nullable NSDate *)connectEndDate 126 129 { 127 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.connectEnd);130 return networkLoadMetricsDate(_metrics.connectEnd); 128 131 } 129 132 … … 131 134 - (nullable NSDate *)requestStartDate 132 135 { 133 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.requestStart);136 return networkLoadMetricsDate(_metrics.requestStart); 134 137 } 135 138 … … 137 140 - (nullable NSDate *)responseStartDate 138 141 { 139 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.responseStart);142 return networkLoadMetricsDate(_metrics.responseStart); 140 143 } 141 144 … … 143 146 - (nullable NSDate *)responseEndDate 144 147 { 145 return networkLoadMetricsDate(_metrics. fetchStart, _metrics.responseEnd);148 return networkLoadMetricsDate(_metrics.responseEnd); 146 149 } 147 150 -
trunk/Source/WebCore/platform/network/curl/CurlContext.cpp
r278253 r278391 761 761 } 762 762 763 std::optional<NetworkLoadMetrics> CurlHandle::getNetworkLoadMetrics( const WTF::Seconds& domainLookupStart)763 std::optional<NetworkLoadMetrics> CurlHandle::getNetworkLoadMetrics(MonotonicTime startTime) 764 764 { 765 765 double nameLookup = 0.0; … … 794 794 NetworkLoadMetrics networkLoadMetrics; 795 795 796 networkLoadMetrics.domainLookupStart = domainLookupStart;797 networkLoadMetrics.domainLookupEnd = domainLookupStart+ Seconds(nameLookup);798 networkLoadMetrics.connectStart = domainLookupStart + Seconds(nameLookup);799 networkLoadMetrics.connectEnd = domainLookupStart+ Seconds(connect);796 networkLoadMetrics.domainLookupStart = startTime; 797 networkLoadMetrics.domainLookupEnd = startTime + Seconds(nameLookup); 798 networkLoadMetrics.connectStart = networkLoadMetrics.domainLookupEnd; 799 networkLoadMetrics.connectEnd = startTime + Seconds(connect); 800 800 801 801 if (appConnect > 0.0) { 802 networkLoadMetrics.secureConnectionStart = domainLookupStart + Seconds(connect);803 networkLoadMetrics.connectEnd = domainLookupStart+ Seconds(appConnect);802 networkLoadMetrics.secureConnectionStart = networkLoadMetrics.connectEnd; 803 networkLoadMetrics.connectEnd = startTime + Seconds(appConnect); 804 804 } 805 805 806 806 networkLoadMetrics.requestStart = networkLoadMetrics.connectEnd; 807 networkLoadMetrics.responseStart = domainLookupStart+ Seconds(startTransfer);807 networkLoadMetrics.responseStart = startTime + Seconds(startTransfer); 808 808 809 809 if (version == CURL_HTTP_VERSION_1_0) -
trunk/Source/WebCore/platform/network/curl/CurlContext.h
r278253 r278391 31 31 32 32 #include <wtf/Lock.h> 33 #include <wtf/MonotonicTime.h> 33 34 #include <wtf/NeverDestroyed.h> 34 35 #include <wtf/Noncopyable.h> … … 297 298 std::optional<long> getProxyAuthAvail(); 298 299 std::optional<long> getHttpVersion(); 299 std::optional<NetworkLoadMetrics> getNetworkLoadMetrics( const WTF::Seconds& domainLookupStart);300 std::optional<NetworkLoadMetrics> getNetworkLoadMetrics(MonotonicTime startTime); 300 301 void addExtraNetworkLoadMetrics(NetworkLoadMetrics&); 301 302 -
trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp
r277920 r278391 111 111 ASSERT(isMainThread()); 112 112 113 if (std::isnan(m_requestStartTime))114 m_requestStartTime = MonotonicTime::now().isolatedCopy();115 116 113 if (m_request.url().isLocalFile()) 117 114 invokeDidReceiveResponseForFile(m_request.url()); … … 457 454 458 455 finalizeTransfer(); 459 callClient([ requestStartTime = m_requestStartTime.isolatedCopy(),networkLoadMetrics = WTFMove(metrics)](CurlRequest& request, CurlRequestClient& client) mutable {460 networkLoadMetrics.responseEnd = MonotonicTime::now() - requestStartTime;456 callClient([networkLoadMetrics = WTFMove(metrics)](CurlRequest& request, CurlRequestClient& client) mutable { 457 networkLoadMetrics.responseEnd = MonotonicTime::now(); 461 458 networkLoadMetrics.markComplete(); 462 459 … … 727 724 ASSERT(m_curlHandle); 728 725 729 auto domainLookupStart = m_performStartTime - m_requestStartTime; 730 auto networkLoadMetrics = m_curlHandle->getNetworkLoadMetrics(domainLookupStart); 726 auto networkLoadMetrics = m_curlHandle->getNetworkLoadMetrics(m_performStartTime); 731 727 if (!networkLoadMetrics) 732 728 return NetworkLoadMetrics(); -
trunk/Source/WebCore/platform/network/curl/CurlRequest.h
r276211 r278391 77 77 bool isServerTrustEvaluationDisabled() { return m_shouldDisableServerTrustEvaluation; } 78 78 void disableServerTrustEvaluation() { m_shouldDisableServerTrustEvaluation = true; } 79 void setStartTime(const MonotonicTime& startTime) { m_requestStartTime = startTime.isolatedCopy(); }80 79 81 80 void start(); … … 211 210 bool m_captureExtraMetrics; 212 211 HTTPHeaderMap m_requestHeaders; 213 MonotonicTime m_requestStartTime { MonotonicTime::nan() };214 212 MonotonicTime m_performStartTime; 215 213 size_t m_totalReceivedSize { 0 }; -
trunk/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
r278253 r278391 82 82 } 83 83 84 d->m_startTime = MonotonicTime::now();85 86 84 d->m_curlRequest = createCurlRequest(WTFMove(request)); 87 85 … … 91 89 } 92 90 93 d->m_curlRequest->setStartTime(d->m_startTime);94 91 d->m_curlRequest->start(); 95 92 … … 366 363 d->m_curlRequest->setAuthenticationScheme(protectionSpace.authenticationScheme()); 367 364 d->m_curlRequest->setUserPass(credential.user(), credential.password()); 368 d->m_curlRequest->setStartTime(d->m_startTime);369 365 d->m_curlRequest->start(); 370 366 } … … 383 379 RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(context, request, &client, defersLoading, shouldContentSniff, shouldContentEncodingSniff)); 384 380 handle->d->m_messageQueue = &client.messageQueue(); 385 handle->d->m_startTime = MonotonicTime::now();386 381 387 382 if (request.url().protocolIsData()) { … … 398 393 } 399 394 400 handle->d->m_curlRequest->setStartTime(handle->d->m_startTime);401 395 handle->d->m_curlRequest->start(); 402 396 … … 486 480 newRequest.clearHTTPAuthorization(); 487 481 newRequest.clearHTTPOrigin(); 488 d->m_startTime = WTF::MonotonicTime::now();489 482 } 490 483 … … 517 510 d->m_curlRequest->setUserPass(credential->user(), credential->password()); 518 511 519 d->m_curlRequest->setStartTime(d->m_startTime);520 512 d->m_curlRequest->start(); 521 513 } -
trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm
r277740 r278391 268 268 [connection() setDelegateQueue:operationQueueForAsyncClients()]; 269 269 [connection() start]; 270 d->m_startTime = MonotonicTime::now(); 270 271 271 272 LOG(Network, "Handle %p starting connection %p for %@", this, connection(), firstRequest().nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody)); -
trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.h
r278253 r278391 25 25 26 26 #import <dispatch/dispatch.h> 27 #import <wtf/Box.h> 27 28 #import <wtf/Function.h> 28 29 #import <wtf/Lock.h> … … 34 35 35 36 namespace WebCore { 37 class NetworkLoadMetrics; 36 38 class ResourceHandle; 37 39 class SynchronousLoaderMessageQueue; -
trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm
r278253 r278391 35 35 #import "ResourceRequest.h" 36 36 #import "ResourceResponse.h" 37 #import "SecurityOrigin.h" 37 38 #import "SharedBuffer.h" 38 39 #import "SynchronousLoaderClient.h" … … 148 149 if (m_handle->firstRequest().httpContentType().isEmpty()) 149 150 redirectRequest.clearHTTPContentType(); 151 152 // Check if the redirected url is allowed to access the redirecting url's timing information. 153 m_handle->setHasCrossOriginRedirect(!WebCore::SecurityOrigin::create(redirectRequest.url())->canRequest(redirectResponse.get().URL)); 154 m_handle->incrementRedirectCount(); 155 150 156 m_handle->willSendRequest(WTFMove(redirectRequest), redirectResponse.get(), [self, protectedSelf = WTFMove(protectedSelf)](ResourceRequest&& request) { 151 157 m_requestResult = request.nsURLRequest(HTTPBodyUpdatePolicy::UpdateHTTPBody); … … 252 258 [r _setMIMEType:@"text/html"]; 253 259 260 auto metrics = copyTimingData(connection.get(), *m_handle); 254 261 ResourceResponse resourceResponse(r.get()); 255 262 resourceResponse.setSource(ResourceResponse::Source::Network); 256 resourceResponse.setDeprecatedNetworkLoadMetrics(copyTimingData(connection.get())); 263 resourceResponse.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics> { metrics }); 264 265 m_handle->setNetworkLoadMetrics(WTFMove(metrics)); 257 266 258 267 m_handle->didReceiveResponse(WTFMove(resourceResponse), [self, protectedSelf = WTFMove(protectedSelf)] { … … 316 325 LOG(Network, "Handle %p delegate connectionDidFinishLoading:%p", m_handle, connection); 317 326 318 auto work = [self = self, protectedSelf = retainPtr(self), connection = retainPtr(connection)] () mutable { 327 double responseEndTime = [[[connection _timingData] objectForKey:@"_kCFNTimingDataResponseEnd"] doubleValue]; 328 329 auto work = [self = self, protectedSelf = retainPtr(self), connection = retainPtr(connection), responseEndTime] () mutable { 319 330 if (!m_handle || !m_handle->client()) 320 331 return; 321 332 322 if (auto metrics = copyTimingData(connection.get())) { 323 double responseEndTime = [[[connection _timingData] objectForKey:@"_kCFNTimingDataResponseEnd"] doubleValue]; 324 metrics->responseEnd = Seconds(responseEndTime <= 0 ? metrics->responseStart.value() : responseEndTime - metrics->fetchStart.value()); 333 if (auto metrics = m_handle->networkLoadMetrics()) { 334 if (responseEndTime) 335 metrics->responseEnd = WallTime::fromRawSeconds(adoptNS([[NSDate alloc] initWithTimeIntervalSinceReferenceDate:responseEndTime]).get().timeIntervalSince1970).approximateMonotonicTime(); 336 else 337 metrics->responseEnd = metrics->responseStart; 325 338 metrics->markComplete(); 326 339 m_handle->client()->didFinishLoading(m_handle, *metrics); -
trunk/Source/WebCore/platform/network/soup/ResourceRequest.h
r273236 r278391 66 66 void setAcceptEncoding(bool acceptEncoding) { m_acceptEncoding = acceptEncoding; } 67 67 68 void incrementRedirectCount() { m_redirectCount++; } 69 uint16_t redirectCount() const { return m_redirectCount; } 70 68 71 void updateSoupMessageBody(SoupMessage*, BlobRegistryImpl&) const; 69 72 void updateSoupMessageHeaders(SoupMessageHeaders*) const; … … 90 93 91 94 bool m_acceptEncoding { true }; 95 uint16_t m_redirectCount { 0 }; 92 96 }; 93 97 … … 105 109 106 110 encoder << static_cast<bool>(m_acceptEncoding); 111 encoder << m_redirectCount; 107 112 } 108 113 … … 128 133 m_acceptEncoding = acceptEncoding; 129 134 135 uint16_t redirectCount; 136 if (!decoder.decode(redirectCount)) 137 return false; 138 m_redirectCount = redirectCount; 139 130 140 return true; 131 141 } -
trunk/Source/WebKit/ChangeLog
r278383 r278391 1 2021-06-02 Alex Christensen <achristensen@webkit.org> 2 3 Fix WPT test resource-timing/cross-origin-redirects.html 4 https://bugs.webkit.org/show_bug.cgi?id=190523 5 <rdar://45227788> 6 7 Reviewed by Brady Eidson. 8 9 * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm: 10 (WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection): 11 * NetworkProcess/cocoa/NetworkSessionCocoa.mm: 12 (-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]): 13 (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]): 14 * NetworkProcess/soup/NetworkDataTaskSoup.cpp: 15 (WebKit::NetworkDataTaskSoup::NetworkDataTaskSoup): 16 (WebKit::NetworkDataTaskSoup::clearRequest): 17 (WebKit::NetworkDataTaskSoup::resume): 18 (WebKit::NetworkDataTaskSoup::didSendRequest): 19 (WebKit::NetworkDataTaskSoup::dispatchDidCompleteWithError): 20 (WebKit::NetworkDataTaskSoup::continueHTTPRedirection): 21 (WebKit::NetworkDataTaskSoup::networkEvent): 22 (WebKit::NetworkDataTaskSoup::didStartRequest): 23 (WebKit::NetworkDataTaskSoup::didRestart): 24 1 25 2021-06-02 Brent Fulgham <bfulgham@apple.com> 2 26 -
trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm
r278253 r278391 459 459 { 460 460 WTFEmitSignpost(m_task.get(), "DataTask", "redirect"); 461 462 // Check if the redirected url is allowed to access the redirecting url's timing information. 463 // FIXME: This should not set back to true after another same-origin redirect once it has been set to true. 464 networkLoadMetrics().hasCrossOriginRedirect = !WebCore::SecurityOrigin::create(request.url())->canRequest(redirectResponse.url()); 461 465 462 466 if (redirectResponse.httpStatusCode() == 307 || redirectResponse.httpStatusCode() == 308) { -
trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
r278253 r278391 775 775 LOG(NetworkSession, "%llu didFinishCollectingMetrics", task.taskIdentifier); 776 776 if (auto* networkDataTask = [self existingTask:task]) { 777 NSURLSessionTaskTransactionMetrics *m = metrics.transactionMetrics.lastObject; 778 NSDate *fetchStartDate = m.fetchStartDate; 779 NSTimeInterval domainLookupStartInterval = m.domainLookupStartDate ? [m.domainLookupStartDate timeIntervalSinceDate:fetchStartDate] : -1; 780 NSTimeInterval domainLookupEndInterval = m.domainLookupEndDate ? [m.domainLookupEndDate timeIntervalSinceDate:fetchStartDate] : -1; 781 NSTimeInterval connectStartInterval = m.connectStartDate ? [m.connectStartDate timeIntervalSinceDate:fetchStartDate] : -1; 782 NSTimeInterval secureConnectionStartInterval = m.secureConnectionStartDate ? [m.secureConnectionStartDate timeIntervalSinceDate:fetchStartDate] : -1; 783 NSTimeInterval connectEndInterval = m.connectEndDate ? [m.connectEndDate timeIntervalSinceDate:fetchStartDate] : -1; 784 NSTimeInterval requestStartInterval = [m.requestStartDate timeIntervalSinceDate:fetchStartDate]; 785 NSTimeInterval responseStartInterval = [m.responseStartDate timeIntervalSinceDate:fetchStartDate]; 786 NSTimeInterval responseEndInterval = [m.responseEndDate timeIntervalSinceDate:fetchStartDate]; 777 NSArray<NSURLSessionTaskTransactionMetrics *> *transactionMetrics = metrics.transactionMetrics; 778 NSURLSessionTaskTransactionMetrics *m = transactionMetrics.lastObject; 779 780 auto dateToMonotonicTime = [] (NSDate *date) { 781 if (auto interval = date.timeIntervalSince1970) 782 return WallTime::fromRawSeconds(interval).approximateMonotonicTime(); 783 return MonotonicTime { }; 784 }; 787 785 788 786 auto& networkLoadMetrics = networkDataTask->networkLoadMetrics(); 789 networkLoadMetrics.fetchStart = Seconds(fetchStartDate.timeIntervalSince1970); 790 networkLoadMetrics.domainLookupStart = Seconds(domainLookupStartInterval); 791 networkLoadMetrics.domainLookupEnd = Seconds(domainLookupEndInterval); 792 networkLoadMetrics.connectStart = Seconds(connectStartInterval); 787 networkLoadMetrics.redirectStart = dateToMonotonicTime(transactionMetrics.firstObject.fetchStartDate); 788 networkLoadMetrics.fetchStart = dateToMonotonicTime(m.fetchStartDate); 789 networkLoadMetrics.domainLookupStart = dateToMonotonicTime(m.domainLookupStartDate); 790 networkLoadMetrics.domainLookupEnd = dateToMonotonicTime(m.domainLookupEndDate); 791 networkLoadMetrics.connectStart = dateToMonotonicTime(m.connectStartDate); 793 792 if (m.reusedConnection && [m.response.URL.scheme isEqualToString:@"https"]) 794 793 networkLoadMetrics.secureConnectionStart = WebCore::reusedTLSConnectionSentinel; 795 794 else 796 networkLoadMetrics.secureConnectionStart = Seconds(secureConnectionStartInterval);797 networkLoadMetrics.connectEnd = Seconds(connectEndInterval);798 networkLoadMetrics.requestStart = Seconds(requestStartInterval);799 networkLoadMetrics.responseStart = Seconds(responseStartInterval);800 networkLoadMetrics.responseEnd = Seconds(responseEndInterval);795 networkLoadMetrics.secureConnectionStart = dateToMonotonicTime(m.secureConnectionStartDate); 796 networkLoadMetrics.connectEnd = dateToMonotonicTime(m.connectEndDate); 797 networkLoadMetrics.requestStart = dateToMonotonicTime(m.requestStartDate); 798 networkLoadMetrics.responseStart = dateToMonotonicTime(m.responseStartDate); 799 networkLoadMetrics.responseEnd = dateToMonotonicTime(m.responseEndDate); 801 800 networkLoadMetrics.markComplete(); 801 networkLoadMetrics.redirectCount = metrics.redirectCount; 802 802 networkLoadMetrics.protocol = String(m.networkProtocolName); 803 803 #if HAVE(CFNETWORK_METRICS_CONNECTION_PROPERTIES) … … 882 882 883 883 NegotiatedLegacyTLS negotiatedLegacyTLS = NegotiatedLegacyTLS::No; 884 NSURLSessionTask TransactionMetrics *metrics = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;884 NSURLSessionTaskMetrics *taskMetrics = dataTask._incompleteTaskMetrics; 885 885 #if HAVE(TLS_PROTOCOL_VERSION_T) 886 NSURLSessionTaskTransactionMetrics *metrics = taskMetrics.transactionMetrics.lastObject; 886 887 auto tlsVersion = (tls_protocol_version_t)metrics.negotiatedTLSProtocolVersion.unsignedShortValue; 887 888 if (tlsVersion == tls_protocol_version_TLSv10 || tlsVersion == tls_protocol_version_TLSv11) 888 889 negotiatedLegacyTLS = NegotiatedLegacyTLS::Yes; 889 UNUSED_PARAM(metrics);890 890 #else // We do not need to check _TLSNegotiatedProtocolVersion if we have metrics.negotiatedTLSProtocolVersion because it works at response time even before rdar://problem/56522601 891 891 ALLOW_DEPRECATED_DECLARATIONS_BEGIN … … 910 910 resourceResponse.disableLazyInitialization(); 911 911 912 resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData( metrics));912 resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics, networkDataTask->networkLoadMetrics().hasCrossOriginRedirect)); 913 913 914 914 networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) { -
trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
r278185 r278391 52 52 , m_shouldRelaxThirdPartyCookieBlocking(shouldRelaxThirdPartyCookieBlocking) 53 53 { 54 m_startTime = MonotonicTime::now();55 56 54 auto request = requestWithCredentials; 57 55 if (request.url().protocolIsInHTTPFamily()) { … … 80 78 m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic); 81 79 } 82 m_curlRequest->setStartTime(m_startTime);83 80 m_curlRequest->start(); 84 81 } … … 312 309 m_curlRequest->cancel(); 313 310 314 if (newRequest.url().protocolIsInHTTPFamily() && isCrossOrigin)315 m_startTime = MonotonicTime::now();316 317 311 auto requestCopy = newRequest; 318 312 restrictRequestReferrerToOriginIfNeeded(requestCopy); … … 322 316 m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic); 323 317 } 324 m_curlRequest->setStartTime(m_startTime);325 318 m_curlRequest->start(); 326 319 … … 443 436 if (shouldDisableServerTrustEvaluation) 444 437 m_curlRequest->disableServerTrustEvaluation(); 445 m_curlRequest->setStartTime(m_startTime);446 438 m_curlRequest->start(); 447 439 -
trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h
r275454 r278391 100 100 unsigned m_redirectCount { 0 }; 101 101 unsigned m_authFailureCount { 0 }; 102 MonotonicTime m_startTime;103 102 104 103 WebCore::FrameIdentifier m_frameID; -
trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
r278253 r278391 67 67 if (request.url().protocolIsInHTTPFamily()) { 68 68 #if USE(SOUP2) 69 m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch(); 69 m_networkLoadMetrics.fetchStart = MonotonicTime::now(); 70 m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; 70 71 #endif 71 72 auto url = request.url(); … … 168 169 } 169 170 171 m_networkLoadMetrics.redirectCount = m_currentRequest.redirectCount(); 172 170 173 unsigned messageFlags = SOUP_MESSAGE_NO_REDIRECT; 171 174 #if !USE(SOUP2) … … 268 271 auto* metrics = soup_message_get_metrics(m_soupMessage.get()); 269 272 auto responseEnd = Seconds::fromMicroseconds(soup_message_metrics_get_response_end(metrics)); 270 m_networkLoadMetrics.responseEnd = responseEnd ? responseEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);273 m_networkLoadMetrics.responseEnd = MonotonicTime::fromRawSeconds(responseEnd.seconds()); 271 274 m_networkLoadMetrics.markComplete(); 272 275 } … … 310 313 soup_session_send_async(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), m_soupMessage.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(), 311 314 reinterpret_cast<GAsyncReadyCallback>(sendRequestCallback), new SendRequestData({ m_soupMessage, WTFMove(protectedThis) })); 312 #if !USE(SOUP2)313 315 if (!g_cancellable_is_cancelled(protectCancellable.get()) && !m_networkLoadMetrics.fetchStart) { 316 #if USE(SOUP2) 317 m_networkLoadMetrics.fetchStart = MonotonicTime::now(); 318 #else 314 319 auto* metrics = soup_message_get_metrics(m_soupMessage.get()); 315 m_networkLoadMetrics.fetchStart = Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics)); 320 m_networkLoadMetrics.fetchStart = MonotonicTime::fromRawSeconds(Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics)).seconds()); 321 #endif 322 if (!m_networkLoadMetrics.redirectStart) 323 m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; 316 324 } 317 #endif318 325 } 319 326 return; … … 472 479 473 480 #if USE(SOUP2) 474 m_networkLoadMetrics.responseStart = MonotonicTime::now() .secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;481 m_networkLoadMetrics.responseStart = MonotonicTime::now(); 475 482 #endif 476 483 … … 534 541 { 535 542 #if USE(SOUP2) 536 m_networkLoadMetrics.responseEnd = MonotonicTime::now() .secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;543 m_networkLoadMetrics.responseEnd = MonotonicTime::now(); 537 544 m_networkLoadMetrics.markComplete(); 538 545 #endif … … 837 844 838 845 static const unsigned maxRedirects = 20; 839 if (m_ redirectCount++> maxRedirects) {846 if (m_currentRequest.redirectCount() > maxRedirects) { 840 847 #if USE(SOUP2) 841 848 didFail(ResourceError::transportError(m_currentRequest.url(), SOUP_STATUS_TOO_MANY_REDIRECTS, "Too many redirects")); … … 845 852 return; 846 853 } 854 855 m_currentRequest.incrementRedirectCount(); 856 m_networkLoadMetrics.redirectCount = m_currentRequest.redirectCount(); 847 857 848 858 ResourceRequest request = m_currentRequest; … … 851 861 redirectedURL.setFragmentIdentifier(request.url().fragmentIdentifier()); 852 862 request.setURL(redirectedURL); 863 864 // Check if the redirected url is allowed to access the redirecting url's timing information. 865 m_networkLoadMetrics.hasCrossOriginRedirect = !SecurityOrigin::create(m_currentRequest.url())->canRequest(request.url()); 853 866 854 867 // Clear the user agent to ensure a new one is computed. … … 897 910 898 911 auto response = ResourceResponse(m_response); 899 m_client->willPerformHTTPRedirection(WTFMove(response), WTFMove(request), [this, protectedThis = makeRef(*this), isCrossOrigin,wasBlockingCookies, userAgent = WTFMove(userAgent)](const ResourceRequest& newRequest) {912 m_client->willPerformHTTPRedirection(WTFMove(response), WTFMove(request), [this, protectedThis = makeRef(*this), wasBlockingCookies, userAgent = WTFMove(userAgent)](const ResourceRequest& newRequest) { 900 913 if (newRequest.isNull() || m_state == State::Canceling) 901 914 return; … … 903 916 auto request = newRequest; 904 917 if (request.url().protocolIsInHTTPFamily()) { 905 if (isCrossOrigin) { 906 m_networkLoadMetrics = { }; 907 #if USE(SOUP2) 908 m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch(); 909 #endif 910 } else { 918 m_networkLoadMetrics.fetchStart = { }; 911 919 #if !USE(SOUP2) 912 m_networkLoadMetrics.responseEnd = { }; 913 m_networkLoadMetrics.complete = false; 914 #endif 915 } 916 920 m_networkLoadMetrics.responseEnd = { }; 921 m_networkLoadMetrics.complete = false; 922 #endif 917 923 applyAuthenticationToRequest(request); 918 924 … … 1113 1119 auto* metrics = soup_message_get_metrics(m_soupMessage.get()); 1114 1120 auto responseStart = Seconds::fromMicroseconds(soup_message_metrics_get_response_start(metrics)); 1115 m_networkLoadMetrics.responseStart = responseStart - m_networkLoadMetrics.fetchStart;1121 m_networkLoadMetrics.responseStart = MonotonicTime::fromRawSeconds(responseStart.seconds()); 1116 1122 #endif 1117 1123 … … 1362 1368 void NetworkDataTaskSoup::networkEvent(GSocketClientEvent event, GIOStream* stream) 1363 1369 { 1364 Seconds deltaTime = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;1370 auto time = MonotonicTime::now(); 1365 1371 switch (event) { 1366 1372 case G_SOCKET_CLIENT_RESOLVING: 1367 m_networkLoadMetrics.domainLookupStart = deltaTime;1373 m_networkLoadMetrics.domainLookupStart = time; 1368 1374 break; 1369 1375 case G_SOCKET_CLIENT_RESOLVED: 1370 m_networkLoadMetrics.domainLookupEnd = deltaTime;1376 m_networkLoadMetrics.domainLookupEnd = time; 1371 1377 break; 1372 1378 case G_SOCKET_CLIENT_CONNECTING: 1373 m_networkLoadMetrics.connectStart = deltaTime;1379 m_networkLoadMetrics.connectStart = time; 1374 1380 break; 1375 1381 case G_SOCKET_CLIENT_CONNECTED: … … 1389 1395 break; 1390 1396 case G_SOCKET_CLIENT_TLS_HANDSHAKING: 1391 m_networkLoadMetrics.secureConnectionStart = deltaTime;1397 m_networkLoadMetrics.secureConnectionStart = time; 1392 1398 RELEASE_ASSERT(G_IS_TLS_CONNECTION(stream)); 1393 1399 g_object_set_data(G_OBJECT(stream), "wk-soup-message", m_soupMessage.get()); … … 1397 1403 break; 1398 1404 case G_SOCKET_CLIENT_COMPLETE: 1399 m_networkLoadMetrics.connectEnd = deltaTime;1405 m_networkLoadMetrics.connectEnd = time; 1400 1406 break; 1401 1407 default: … … 1460 1466 { 1461 1467 #if USE(SOUP2) 1462 m_networkLoadMetrics.requestStart = MonotonicTime::now() .secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;1468 m_networkLoadMetrics.requestStart = MonotonicTime::now(); 1463 1469 #else 1464 1470 auto* metrics = soup_message_get_metrics(m_soupMessage.get()); … … 1470 1476 auto requestStart = Seconds::fromMicroseconds(soup_message_metrics_get_request_start(metrics)); 1471 1477 1472 m_networkLoadMetrics.domainLookupStart = domainLookupStart ? domainLookupStart - m_networkLoadMetrics.fetchStart : Seconds(-1);1473 m_networkLoadMetrics.domainLookupEnd = domainLookupEnd ? domainLookupEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);1474 m_networkLoadMetrics.connectStart = connectStart ? connectStart - m_networkLoadMetrics.fetchStart : Seconds(-1);1475 m_networkLoadMetrics.connectEnd = connectEnd ? connectEnd - m_networkLoadMetrics.fetchStart : Seconds(-1);1476 m_networkLoadMetrics.secureConnectionStart = secureConnectionStart ? secureConnectionStart - m_networkLoadMetrics.fetchStart : Seconds(-1);1477 m_networkLoadMetrics.requestStart = requestStart - m_networkLoadMetrics.fetchStart;1478 m_networkLoadMetrics.domainLookupStart = MonotonicTime::fromRawSeconds(domainLookupStart.seconds()); 1479 m_networkLoadMetrics.domainLookupEnd = MonotonicTime::fromRawSeconds(domainLookupEnd.seconds()); 1480 m_networkLoadMetrics.connectStart = MonotonicTime::fromRawSeconds(connectStart.seconds()); 1481 m_networkLoadMetrics.connectEnd = MonotonicTime::fromRawSeconds(connectEnd.seconds()); 1482 m_networkLoadMetrics.secureConnectionStart = MonotonicTime::fromRawSeconds(secureConnectionStart.seconds()); 1483 m_networkLoadMetrics.requestStart = MonotonicTime::fromRawSeconds(requestStart.seconds()); 1478 1484 #endif 1479 1485 } … … 1494 1500 m_networkLoadMetrics = { }; 1495 1501 #if USE(SOUP2) 1496 m_networkLoadMetrics.fetchStart = MonotonicTime::now() .secondsSinceEpoch();1502 m_networkLoadMetrics.fetchStart = MonotonicTime::now(); 1497 1503 #else 1498 1504 auto* metrics = soup_message_get_metrics(m_soupMessage.get()); 1499 m_networkLoadMetrics.fetchStart = Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics));1505 m_networkLoadMetrics.fetchStart = MonotonicTime::fromRawSeconds(Seconds::fromMicroseconds(soup_message_metrics_get_fetch_start(metrics)).seconds()); 1500 1506 m_currentRequest.updateSoupMessageBody(m_soupMessage.get(), m_session->blobRegistry()); 1501 1507 #endif 1508 m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart; 1502 1509 } 1503 1510 -
trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h
r278253 r278391 196 196 CString m_sniffedContentType; 197 197 Vector<char> m_readBuffer; 198 unsigned m_redirectCount { 0 };199 198 uint64_t m_bodyDataTotalBytesSent { 0 }; 200 199 GRefPtr<GFile> m_downloadDestinationFile;
Note:
See TracChangeset
for help on using the changeset viewer.