⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278391 in webkit


Ignore:
Timestamp:
Jun 2, 2021, 6:25:53 PM (5 years ago)
Author:
achristensen@apple.com
Message:

Fix WPT test resource-timing/cross-origin-redirects.html
https://bugs.webkit.org/show_bug.cgi?id=190523
<rdar://45227788>

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

  • web-platform-tests/navigation-timing/nav2_test_redirect_server-expected.txt:
  • web-platform-tests/navigation-timing/nav2_test_redirect_server.html:

Sometimes, with our use of Performance::reduceTimeResolution, the event times are equal to each other.
Allow this.

  • web-platform-tests/resource-timing/cross-origin-redirects-expected.txt: Added.
  • web-platform-tests/resource-timing/cross-origin-redirects.html: Added.
  • web-platform-tests/resource-timing/resources/entry-invariants.js: Added.

(const.assert_all_equal_):
(const.assert_ordered_):
(const.assert_zeroed_):
(const.assert_not_negative_):
(const.assert_positive_):
(const.attribute_test_internal):
(async const):
(const.attribute_test_with_validator):

  • web-platform-tests/resource-timing/resources/resource-loaders.js: Added.

(const.load.font.path.return.document.fonts.ready.then):
(const.load.stylesheet.async path):
(const.load.iframe.async path):
(const.load.script.async path):
(const.load.xhr_sync.async path):

Source/WebCore:

Test: imported/w3c/web-platform-tests/resource-timing/cross-origin-redirects.html

This test took more to fix than I thought it would. We used to collect our timing data
from various sources into various structures, mostly based on Google's work from 2010 with
a few things tacked on to it. The timing specifications have changed considerably in the
last 11 years, and so should the shape of the structures we put the data into.

We used to have a LoadTiming structure in various places that claimed to contain the redirect times,
but markRedirectStart and markRedirectEnd were never called. Instead we tried to collect this data
from the SubResourceLoader and DocumentLoader reporting redirects in the web process. This wasn't great.
Redirect timing is best collected in the network process by the framework doing the redirecting,
and now we have the NSURLSessionTaskMetrics API to get the data we need.

I've made NetworkLoadMetrics the structure that contains all the network load metrics from the network process.
DocumentEventTiming is owned in the web process by the Document, and it contains the load event timing data.
ResourceLoadTiming is owned by the ResourceLoader, and it contains the fetch start and end times including the
parts of the fetch algorithm that happen in the web process.
DocumentLoadTiming inherits from it and is owned by the DocumentLoader, which reflects the fact that
PerformanceNavigationTiming inherits from PerformanceResourceTiming in the specs.
With these structures in place, we now have the infrastructure to collect timing data and expose it correctly.

Another thing that has changed is that these structures consistently store the timing data in the MonotonicTime type,
which is the number of seconds since the machine restarted. NetworkLoadMetrics used to confusingly store fetch
start time and then other network times as deltas from it, and we would pretend that fetch start time was the same
as the fetch start time in the web process and calculate everything from the deltas. This is an unfortunate
consequence of my younger self not realizing that the double values from NSURLConnection._timingData are values to
be put into [NSDate initWithTimeIntervalSinceReferenceDate] then pulled out with timeIntervalSince1970 to get
WallTime. I was confused because they weren't WallTime or MonotonicTime, so I only dealt with them as deltas
from each other. Consistently using MonotonicTime makes all this code much more straightforward.

I also use std::numeric_limits<uint64_t>::max() instead of std::numeric_limits<uint32_t>::max() as a sentinel value
for requestHeaderBytesSent and responseHeaderBytesReceived to make everything more sane. I'm not too worried about
the metrics of downloads of exactly 4GB, but they should also be fixed.

A consequence of collecting the redirect times in the network process is that we have to move the
SecurityOrigin::canRequest checks to see if the redirects are same-origin to ResourceHandle and NetworkDataTask.

  • Headers.cmake:
  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/Document.cpp:

(WebCore::Document::setReadyState):
(WebCore::Document::finishedParsing):
(WebCore::Document::monotonicTimestamp const):

  • dom/Document.h:

(WebCore::Document::eventTiming const):
(WebCore::Document::timing const): Deleted.

  • dom/DocumentEventTiming.h: Copied from Source/WebCore/dom/DocumentTiming.h.
  • inspector/agents/InspectorNetworkAgent.cpp:

(WebCore::InspectorNetworkAgent::buildObjectForTiming):
(WebCore::InspectorNetworkAgent::buildObjectForMetrics):
(WebCore::InspectorNetworkAgent::buildObjectForResourceResponse):
(WebCore::InspectorNetworkAgent::didFinishLoading):

  • inspector/agents/InspectorNetworkAgent.h:
  • loader/DocumentLoadTiming.h: Renamed from Source/WebCore/loader/LoadTiming.h.

(WebCore::DocumentLoadTiming::timeOrigin const):
(WebCore::DocumentLoadTiming::markUnloadEventStart):
(WebCore::DocumentLoadTiming::markUnloadEventEnd):
(WebCore::DocumentLoadTiming::markLoadEventStart):
(WebCore::DocumentLoadTiming::markLoadEventEnd):
(WebCore::DocumentLoadTiming::setHasSameOriginAsPreviousDocument):
(WebCore::DocumentLoadTiming::unloadEventStart const):
(WebCore::DocumentLoadTiming::unloadEventEnd const):
(WebCore::DocumentLoadTiming::loadEventStart const):
(WebCore::DocumentLoadTiming::loadEventEnd const):
(WebCore::DocumentLoadTiming::hasSameOriginAsPreviousDocument const):

  • loader/DocumentLoader.cpp:

(WebCore::DocumentLoader::finishedLoading):
(WebCore::DocumentLoader::willSendRequest):
(WebCore::DocumentLoader::dataReceived):
(WebCore::DocumentLoader::startLoadingMainResource):

  • loader/DocumentLoader.h:

(WebCore::DocumentLoader::timing const):
(WebCore::DocumentLoader::timing):
(WebCore::DocumentLoader::resetTiming):

  • loader/DocumentThreadableLoader.cpp:

(WebCore::DocumentThreadableLoader::loadRequest):

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::dispatchUnloadEvents):

  • loader/LoadTiming.cpp: Removed.
  • loader/ResourceLoadTiming.h: Renamed from Source/WebCore/dom/DocumentTiming.h.

(WebCore::ResourceLoadTiming::markStartTime):
(WebCore::ResourceLoadTiming::markEndTime):
(WebCore::ResourceLoadTiming::startTime const):
(WebCore::ResourceLoadTiming::endTime const):
(WebCore::ResourceLoadTiming::isolatedCopy const):

  • loader/ResourceLoader.cpp:

(WebCore::ResourceLoader::init):

  • loader/ResourceLoader.h:

(WebCore::ResourceLoader::loadTiming):

  • loader/ResourceTiming.cpp:

(WebCore::ResourceTiming::fromMemoryCache):
(WebCore::ResourceTiming::fromLoad):
(WebCore::ResourceTiming::fromSynchronousLoad):
(WebCore::ResourceTiming::ResourceTiming):
(WebCore::ResourceTiming::isolatedCopy const):
(WebCore::ResourceTiming::fromCache): Deleted.

  • loader/ResourceTiming.h:

(WebCore::ResourceTiming::resourceLoadTiming const):
(WebCore::ResourceTiming::ResourceTiming):
(WebCore::ResourceTiming::loadTiming const): Deleted.

  • loader/ResourceTimingInformation.cpp:
  • loader/SubresourceLoader.cpp:

(WebCore::SubresourceLoader::willSendRequestInternal):
(WebCore::SubresourceLoader::didFinishLoading):

  • loader/cache/CachedResource.h:
  • loader/cache/CachedResourceLoader.cpp:

(WebCore::CachedResourceLoader::requestResource):

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::performance const):

  • page/Performance.cpp:

(WebCore::Performance::addNavigationTiming):

  • page/Performance.h:
  • page/PerformanceNavigation.cpp:

(WebCore::PerformanceNavigation::redirectCount const):

  • page/PerformanceNavigationTiming.cpp:

(WebCore::PerformanceNavigationTiming::PerformanceNavigationTiming):
(WebCore::PerformanceNavigationTiming::millisecondsSinceOrigin const):
(WebCore::PerformanceNavigationTiming::sameOriginCheckFails const):
(WebCore::PerformanceNavigationTiming::unloadEventStart const):
(WebCore::PerformanceNavigationTiming::unloadEventEnd const):
(WebCore::PerformanceNavigationTiming::domInteractive const):
(WebCore::PerformanceNavigationTiming::domContentLoadedEventStart const):
(WebCore::PerformanceNavigationTiming::domContentLoadedEventEnd const):
(WebCore::PerformanceNavigationTiming::domComplete const):
(WebCore::PerformanceNavigationTiming::loadEventStart const):
(WebCore::PerformanceNavigationTiming::loadEventEnd const):
(WebCore::PerformanceNavigationTiming::redirectCount const):

  • page/PerformanceNavigationTiming.h:
  • page/PerformanceResourceTiming.cpp:

(WebCore::networkLoadTimeToDOMHighResTimeStamp):
(WebCore::fetchStart):
(WebCore::entryStartTime):
(WebCore::entryEndTime):
(WebCore::PerformanceResourceTiming::redirectStart const):
(WebCore::PerformanceResourceTiming::redirectEnd const):
(WebCore::PerformanceResourceTiming::fetchStart const):
(WebCore::PerformanceResourceTiming::domainLookupStart const):
(WebCore::PerformanceResourceTiming::domainLookupEnd const):
(WebCore::PerformanceResourceTiming::connectStart const):
(WebCore::PerformanceResourceTiming::connectEnd const):
(WebCore::PerformanceResourceTiming::secureConnectionStart const):
(WebCore::PerformanceResourceTiming::requestStart const):
(WebCore::PerformanceResourceTiming::responseStart const):
(WebCore::PerformanceResourceTiming::responseEnd const):
(WebCore::monotonicTimeToDOMHighResTimeStamp): Deleted.
(WebCore::PerformanceResourceTiming::networkLoadTimeToDOMHighResTimeStamp const): Deleted.

  • page/PerformanceResourceTiming.h:
  • page/PerformanceTiming.cpp:

(WebCore::PerformanceTiming::navigationStart const):
(WebCore::PerformanceTiming::unloadEventStart const):
(WebCore::PerformanceTiming::unloadEventEnd const):
(WebCore::PerformanceTiming::redirectStart const):
(WebCore::PerformanceTiming::redirectEnd const):
(WebCore::PerformanceTiming::fetchStart const):
(WebCore::PerformanceTiming::domainLookupStart const):
(WebCore::PerformanceTiming::domainLookupEnd const):
(WebCore::PerformanceTiming::connectStart const):
(WebCore::PerformanceTiming::connectEnd const):
(WebCore::PerformanceTiming::secureConnectionStart const):
(WebCore::PerformanceTiming::requestStart const):
(WebCore::PerformanceTiming::responseStart const):
(WebCore::PerformanceTiming::responseEnd const):
(WebCore::PerformanceTiming::domLoading const):
(WebCore::PerformanceTiming::domInteractive const):
(WebCore::PerformanceTiming::domContentLoadedEventStart const):
(WebCore::PerformanceTiming::domContentLoadedEventEnd const):
(WebCore::PerformanceTiming::domComplete const):
(WebCore::PerformanceTiming::loadEventStart const):
(WebCore::PerformanceTiming::loadEventEnd const):
(WebCore::PerformanceTiming::documentLoader const):
(WebCore::PerformanceTiming::documentEventTiming const):
(WebCore::PerformanceTiming::documentLoadTiming const):
(WebCore::PerformanceTiming::networkLoadMetrics const):
(WebCore::PerformanceTiming::monotonicTimeToIntegerMilliseconds const):
(WebCore::PerformanceTiming::documentTiming const): Deleted.
(WebCore::PerformanceTiming::loadTiming const): Deleted.
(WebCore::PerformanceTiming::resourceLoadTimeRelativeToFetchStart const): Deleted.

  • page/PerformanceTiming.h:
  • platform/network/NetworkLoadMetrics.h:

(WebCore::NetworkLoadMetrics::isolatedCopy const):
(WebCore::NetworkLoadMetrics::operator== const):
(WebCore::NetworkLoadMetrics::encode const):
(WebCore::NetworkLoadMetrics::decode):

  • platform/network/ResourceHandle.cpp:

(WebCore::ResourceHandle::hasCrossOriginRedirect const):
(WebCore::ResourceHandle::setHasCrossOriginRedirect):
(WebCore::ResourceHandle::incrementRedirectCount):
(WebCore::ResourceHandle::redirectCount const):
(WebCore::ResourceHandle::startTimeBeforeRedirects const):
(WebCore::ResourceHandle::networkLoadMetrics):
(WebCore::ResourceHandle::setNetworkLoadMetrics):

  • platform/network/ResourceHandle.h:
  • platform/network/ResourceHandleInternal.h:
  • platform/network/cocoa/NetworkLoadMetrics.mm:

(WebCore::dateToMonotonicTime):
(WebCore::packageTimingData):
(WebCore::copyTimingData):

  • platform/network/cocoa/WebCoreNSURLSession.mm:

(networkLoadMetricsDate):
(-[WebCoreNSURLSessionTaskTransactionMetrics fetchStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics domainLookupStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics domainLookupEndDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics connectStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics secureConnectionStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics connectEndDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics requestStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics responseStartDate]):
(-[WebCoreNSURLSessionTaskTransactionMetrics responseEndDate]):

  • platform/network/curl/CurlContext.cpp:

(WebCore::CurlHandle::getNetworkLoadMetrics):

  • platform/network/curl/CurlContext.h:
  • platform/network/curl/CurlRequest.cpp:

(WebCore::CurlRequest::didCompleteTransfer):
(WebCore::CurlRequest::networkLoadMetrics):

  • platform/network/mac/ResourceHandleMac.mm:

(WebCore::ResourceHandle::start):

  • platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.h:
  • platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm:

(-[WebCoreResourceHandleAsOperationQueueDelegate connection:willSendRequest:redirectResponse:]):
(-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveResponse:]):
(-[WebCoreResourceHandleAsOperationQueueDelegate connectionDidFinishLoading:]):

Source/WebKit:

  • NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:

(WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):

  • NetworkProcess/cocoa/NetworkSessionCocoa.mm:

(-[WKNetworkSessionDelegate URLSession:task:didFinishCollectingMetrics:]):
(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveResponse:completionHandler:]):

  • NetworkProcess/soup/NetworkDataTaskSoup.cpp:

(WebKit::NetworkDataTaskSoup::NetworkDataTaskSoup):
(WebKit::NetworkDataTaskSoup::clearRequest):
(WebKit::NetworkDataTaskSoup::resume):
(WebKit::NetworkDataTaskSoup::didSendRequest):
(WebKit::NetworkDataTaskSoup::dispatchDidCompleteWithError):
(WebKit::NetworkDataTaskSoup::continueHTTPRedirection):
(WebKit::NetworkDataTaskSoup::networkEvent):
(WebKit::NetworkDataTaskSoup::didStartRequest):
(WebKit::NetworkDataTaskSoup::didRestart):

LayoutTests:

  • http/tests/misc/webtiming-slow-load-expected.txt:
  • http/tests/misc/webtiming-slow-load.py:

Our new metrics gathering now matches Firefox instead of Chrome in PerformanceResourceTiming::responseEnd in this edge case of a deprecated API.
Update expectations accordingly.

  • platform/mac-wk1/TestExpectations:

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.

  • platform/win/http/tests/misc/webtiming-one-redirect-expected.txt: Added.
  • platform/win/http/tests/misc/webtiming-slow-load-expected.txt: Copied from LayoutTests/http/tests/misc/webtiming-slow-load-expected.txt.
  • platform/win/http/tests/misc/webtiming-two-redirects-expected.txt: Added.

The network layer is now responsible for counting redirects and providing redirect timings.
Our friend CFURLConnection doesn't have that ability, so it doesn't pass these tests any more.
It never supported any timing APIs and other tests are skipped.

Location:
trunk
Files:
10 added
3 deleted
59 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r278388 r278391  
     12021-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
    1222021-06-02  Amir Mark Jr  <amir_mark@apple.com>
    223
  • trunk/LayoutTests/http/tests/misc/webtiming-slow-load-expected.txt

    r75120 r278391  
    66PASS timing.requestStart is non-zero.
    77PASS timing.responseStart is non-zero.
    8 PASS timing.responseEnd is 0
     8PASS timing.responseEnd is non-zero.
    99PASS successfullyParsed is true
    1010
  • trunk/LayoutTests/http/tests/misc/webtiming-slow-load.py

    r273819 r278391  
    2525    'shouldBeNonZero("timing.requestStart");\n'
    2626    'shouldBeNonZero("timing.responseStart");\n'
    27     'shouldBe("timing.responseEnd", "0");\n'
     27    'shouldBeNonZero("timing.responseEnd");\n'
    2828    '\n'
    2929    '</script>\n'
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r278350 r278391  
     12021-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
    1312021-06-02  Martin Robinson  <mrobinson@igalia.com>
    232
  • 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 false
    21Description
    32
     
    65
    76
    8 FAIL Navigation Timing 2 WPT Error: assert_true: Expected startTime to be no greater than redirectStart. expected true got false
     7PASS Navigation Timing 2 WPT
    98
  • trunk/LayoutTests/imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server.html

    r277767 r278391  
    1414            function verifyTimingEventOrder(eventOrder, timingEntry) {
    1515                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]],
    1717                        "Expected " + eventOrder[i] + " to be no greater than " + eventOrder[i + 1] + ".");
    1818                }
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r278387 r278391  
    583583webkit.org/b/159893 [ Debug ] imported/w3c/web-platform-tests/xhr/event-readystatechange-loaded.any.js [ Pass Failure ]
    584584
     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.
     586imported/w3c/web-platform-tests/navigation-timing/nav2_test_redirect_server.html [ Pass Failure ]
     587
    585588webkit.org/b/160101 userscripts/window-onerror-for-isolated-world-3.html [ Pass Failure ]
    586589
  • trunk/Source/WebCore/ChangeLog

    r278389 r278391  
     12021-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
    12322021-06-02  Alan Bujtas  <zalan@apple.com>
    2233
  • trunk/Source/WebCore/Headers.cmake

    r278354 r278391  
    440440    dom/DeviceOrientationOrMotionPermissionState.h
    441441    dom/Document.h
     442    dom/DocumentEventTiming.h
    442443    dom/DocumentFontLoader.h
    443444    dom/DocumentFragment.h
     
    446447    dom/DocumentMarkerController.h
    447448    dom/DocumentStorageAccess.h
    448     dom/DocumentTiming.h
    449449    dom/DocumentType.h
    450450    dom/Element.h
     
    777777    loader/CrossOriginPreflightResultCache.h
    778778    loader/CustomHeaderFields.h
     779    loader/DocumentLoadTiming.h
    779780    loader/DocumentLoader.h
    780781    loader/DocumentWriter.h
     
    797798    loader/LinkLoaderClient.h
    798799    loader/LoadSchedulingMode.h
    799     loader/LoadTiming.h
    800800    loader/LoaderStrategy.h
    801801    loader/MediaResourceLoader.h
     
    813813    loader/ResourceLoadObserver.h
    814814    loader/ResourceLoadStatistics.h
     815    loader/ResourceLoadTiming.h
    815816    loader/ResourceLoader.h
    816817    loader/ResourceLoaderOptions.h
  • trunk/Source/WebCore/Sources.txt

    r278354 r278391  
    16031603loader/LinkLoader.cpp
    16041604loader/LinkPreloadResourceClients.cpp
    1605 loader/LoadTiming.cpp
    16061605loader/LoaderStrategy.cpp
    16071606loader/MediaResourceLoader.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r278354 r278391  
    19901990                5C53DCEA24468FB400A93124 /* ApplePaySetupWebCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C53DCCB2446449800A93124 /* ApplePaySetupWebCore.h */; settings = {ATTRIBUTES = (Private, ); }; };
    19911991                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, ); }; };
    19921993                5C7C88D81D0F1F4A009D2F6D /* SocketProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
    19931994                5C9C2DB52241A67B00996B0B /* ContentRuleListResults.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C9C2DB32241A67300996B0B /* ContentRuleListResults.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    27272728                868160D618766A130021E79D /* UserActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 868160D2187669C40021E79D /* UserActivity.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27282729                86BE340115058CB200CE0FD8 /* PerformanceEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */; };
    2729                 86D982F7125C154000AD9E3D /* DocumentTiming.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, ); }; };
    27302731                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, ); }; };
    27322733                8A309C9F123950BE00CB9204 /* NestingLevelIncrementer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A309C9E123950BE00CB9204 /* NestingLevelIncrementer.h */; };
    27332734                8A413AE01207BBA50082016E /* ScriptRunner.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A413ADE1207BBA50082016E /* ScriptRunner.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    96969697                5C688AA01D380509000B54FA /* ThreadableWebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableWebSocketChannel.cpp; sourceTree = "<group>"; };
    96979698                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>"; };
    96989700                5C7C88D71D0F1F2B009D2F6D /* SocketProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketProvider.h; sourceTree = "<group>"; };
    96999701                5C97A3361F5F7A6500105207 /* RectEdges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RectEdges.h; sourceTree = "<group>"; };
     
    1143611438                85DF2F690AA3C74300AD64C5 /* HTMLCollection.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLCollection.idl; sourceTree = "<group>"; };
    1143711439                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>"; };
    1143911440                862F129D18C1572C005C54AF /* CountedUserActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountedUserActivity.h; sourceTree = "<group>"; };
    1144011441                86512EDB154A2AEE00A90426 /* PerformanceResourceTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceResourceTiming.cpp; sourceTree = "<group>"; };
     
    1144711448                86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceEntry.h; sourceTree = "<group>"; };
    1144811449                86BE33FC15058CB200CE0FD8 /* PerformanceEntry.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PerformanceEntry.idl; sourceTree = "<group>"; };
    11449                 86D982F6125C154000AD9E3D /* DocumentTiming.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>"; };
    1145011451                8931DE5A14C44C44000DC9D2 /* JSBlobCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBlobCustom.cpp; sourceTree = "<group>"; };
    1145111452                898785F2122E1EAC003AABDA /* JSFileReaderSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFileReaderSync.cpp; sourceTree = "<group>"; };
    1145211453                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>"; };
    1145411455                8A309C9E123950BE00CB9204 /* NestingLevelIncrementer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NestingLevelIncrementer.h; sourceTree = "<group>"; };
    1145511456                8A413ADE1207BBA50082016E /* ScriptRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptRunner.h; sourceTree = "<group>"; };
     
    2779927800                                93E227DB0AF589AD00D48324 /* DocumentLoader.cpp */,
    2780027801                                656D371E0ADBA5DE00A4554D /* DocumentLoader.h */,
     27802                                8A12E35C11FA33280025836A /* DocumentLoadTiming.h */,
    2780127803                                0B9056150F2578BE0095FF6A /* DocumentThreadableLoader.cpp */,
    2780227804                                0B9056160F2578BE0095FF6A /* DocumentThreadableLoader.h */,
     
    2784327845                                51E6820F16387302003BBF3C /* LoaderStrategy.h */,
    2784427846                                E47FC8A125B84D71005495FC /* LoadSchedulingMode.h */,
    27845                                 861C2EA313FB4FDD00062ABB /* LoadTiming.cpp */,
    27846                                 8A12E35C11FA33280025836A /* LoadTiming.h */,
    2784727847                                CEEFCD7719DB31F7003876D7 /* MediaResourceLoader.cpp */,
    2784827848                                CEEFCD7819DB31F7003876D7 /* MediaResourceLoader.h */,
     
    2787927879                                7A929CA11C598378004DF226 /* ResourceLoadStatistics.cpp */,
    2788027880                                7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */,
     27881                                5C6D02FF265C211A002B64FE /* ResourceLoadTiming.h */,
    2788127882                                A5CE9F3E1E4C416B001BBE7C /* ResourceTiming.cpp */,
    2788227883                                A5CE9F3C1E4BC586001BBE7C /* ResourceTiming.h */,
     
    3056530566                                6548E24809E1E04D00AF8020 /* Document.idl */,
    3056630567                                8329A4171EC25B2B008ED4BE /* DocumentAndElementEventHandlers.idl */,
     30568                                86D982F6125C154000AD9E3D /* DocumentEventTiming.h */,
    3056730569                                A8185F3459765765005826D9 /* DocumentFontLoader.cpp */,
    3056830570                                A8185F3559765765005826D9 /* DocumentFontLoader.h */,
     
    3058230584                                6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */,
    3058330585                                6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */,
    30584                                 86D982F6125C154000AD9E3D /* DocumentTiming.h */,
    3058530586                                7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */,
    3058630587                                7CE7FA591EF882300060C9D6 /* DocumentTouch.h */,
     
    3245332454                                7EE6846F12D26E3800E73215 /* DNSResolveQueueCFNet.h in Headers */,
    3245432455                                A8185F4009765766005826D9 /* Document.h in Headers */,
     32456                                86D982F7125C154000AD9E3D /* DocumentEventTiming.h in Headers */,
    3245532457                                A8185F4509765766005826D9 /* DocumentFontLoader.h in Headers */,
    3245632458                                A8185F3D09765766005826D9 /* DocumentFragment.h in Headers */,
     
    3245832460                                41826BF223FB597700B922B1 /* DocumentIdentifier.h in Headers */,
    3245932461                                656D37360ADBA5DE00A4554D /* DocumentLoader.h in Headers */,
     32462                                8A12E35D11FA33280025836A /* DocumentLoadTiming.h in Headers */,
    3246032463                                ED2BA83C09A24B91006C0AC4 /* DocumentMarker.h in Headers */,
    3246132464                                CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */,
     
    3246832471                                71729F7B20F3BA4900801CE6 /* DocumentTimelineOptions.h in Headers */,
    3246932472                                7181A16C244F0F40007D8A24 /* DocumentTimelinesController.h in Headers */,
    32470                                 86D982F7125C154000AD9E3D /* DocumentTiming.h in Headers */,
    3247132473                                A8185F3909765766005826D9 /* DocumentType.h in Headers */,
    3247232474                                973889A1116EA9DC00ADF313 /* DocumentWriter.h in Headers */,
     
    3421634218                                51E6821016387302003BBF3C /* LoaderStrategy.h in Headers */,
    3421734219                                E47FC8A325B84D72005495FC /* LoadSchedulingMode.h in Headers */,
    34218                                 8A12E35D11FA33280025836A /* LoadTiming.h in Headers */,
    3421934220                                06E81ED70AB5D5E900C87837 /* LocalCurrentGraphicsContext.h in Headers */,
    3422034221                                1C43DE6B22AB4B8A001527D9 /* LocalCurrentTraitCollection.h in Headers */,
     
    3502235023                                E4295FA412B0614E00D1ACE0 /* ResourceLoadPriority.h in Headers */,
    3502335024                                7A929CA71C598AA9004DF226 /* ResourceLoadStatistics.h in Headers */,
     35025                                5C6D0301265C211B002B64FE /* ResourceLoadTiming.h in Headers */,
    3502435026                                7EE6846D12D26E3800E79415 /* ResourceRequest.h in Headers */,
    3502535027                                514C767D0CE923A1007EF3CD /* ResourceRequestBase.h in Headers */,
  • trunk/Source/WebCore/dom/Document.cpp

    r278331 r278391  
    13841384    switch (readyState) {
    13851385    case Loading:
    1386         if (!m_documentTiming.domLoading)
    1387             m_documentTiming.domLoading = MonotonicTime::now();
     1386        if (!m_eventTiming.domLoading)
     1387            m_eventTiming.domLoading = MonotonicTime::now();
    13881388        break;
    13891389    case Complete:
    1390         if (!m_documentTiming.domComplete)
    1391             m_documentTiming.domComplete = MonotonicTime::now();
     1390        if (!m_eventTiming.domComplete)
     1391            m_eventTiming.domComplete = MonotonicTime::now();
    13921392        FALLTHROUGH;
    13931393    case Interactive:
    1394         if (!m_documentTiming.domInteractive)
    1395             m_documentTiming.domInteractive = MonotonicTime::now();
     1394        if (!m_eventTiming.domInteractive)
     1395            m_eventTiming.domInteractive = MonotonicTime::now();
    13961396        break;
    13971397    }
     
    60356035    scriptRunner().documentFinishedParsing();
    60366036
    6037     if (!m_documentTiming.domContentLoadedEventStart)
    6038         m_documentTiming.domContentLoadedEventStart = MonotonicTime::now();
     6037    if (!m_eventTiming.domContentLoadedEventStart)
     6038        m_eventTiming.domContentLoadedEventStart = MonotonicTime::now();
    60396039
    60406040    // FIXME: Schedule a task to fire DOMContentLoaded event instead. See webkit.org/b/82931
     
    60426042    dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, Event::CanBubble::Yes, Event::IsCancelable::No));
    60436043
    6044     if (!m_documentTiming.domContentLoadedEventEnd)
    6045         m_documentTiming.domContentLoadedEventEnd = MonotonicTime::now();
     6044    if (!m_eventTiming.domContentLoadedEventEnd)
     6045        m_eventTiming.domContentLoadedEventEnd = MonotonicTime::now();
    60466046
    60476047    if (RefPtr<Frame> frame = this->frame()) {
     
    67466746    auto* loader = this->loader();
    67476747    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();
    67516750}
    67526751
  • trunk/Source/WebCore/dom/Document.h

    r278253 r278391  
    3333#include "ContainerNode.h"
    3434#include "DisabledAdaptations.h"
     35#include "DocumentEventTiming.h"
    3536#include "DocumentIdentifier.h"
    3637#include "DocumentTimelinesController.h"
    37 #include "DocumentTiming.h"
    3838#include "ElementIdentifier.h"
    3939#include "FocusOptions.h"
     
    12081208#endif
    12091209
    1210     const DocumentTiming& timing() const { return m_documentTiming; }
    1211 
    12121210    WEBCORE_EXPORT double monotonicTimestamp() const;
     1211    const DocumentEventTiming& eventTiming() const { return m_eventTiming; }
    12131212
    12141213    int requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
     
    19191918    OptionSet<DisabledAdaptations> m_disabledAdaptations;
    19201919
    1921     DocumentTiming m_documentTiming;
     1920    DocumentEventTiming m_eventTiming;
    19221921
    19231922    RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
  • trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp

    r278253 r278391  
    214214}
    215215
    216 Ref<Protocol::Network::ResourceTiming> InspectorNetworkAgent::buildObjectForTiming(const NetworkLoadMetrics* timing, ResourceLoader& resourceLoader)
    217 {
    218     auto& loadTiming = resourceLoader.loadTiming();
    219 
     216Ref<Protocol::Network::ResourceTiming> InspectorNetworkAgent::buildObjectForTiming(const NetworkLoadMetrics& timing, ResourceLoader& resourceLoader)
     217{
    220218    auto elapsedTimeSince = [&] (const MonotonicTime& time) {
    221219        return m_environment.executionStopwatch().elapsedTimeSince(time).seconds();
    222220    };
    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    };
    228226
    229227    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))
    242240        .release();
    243241}
     
    275273        metrics->setRequestHeaders(buildObjectForHeaders(networkLoadMetrics.requestHeaders));
    276274
    277     if (networkLoadMetrics.requestHeaderBytesSent != std::numeric_limits<uint32_t>::max())
     275    if (networkLoadMetrics.requestHeaderBytesSent != std::numeric_limits<uint64_t>::max())
    278276        metrics->setRequestHeaderBytesSent(networkLoadMetrics.requestHeaderBytesSent);
    279277    if (networkLoadMetrics.requestBodyBytesSent != std::numeric_limits<uint64_t>::max())
    280278        metrics->setRequestBodyBytesSent(networkLoadMetrics.requestBodyBytesSent);
    281     if (networkLoadMetrics.responseHeaderBytesReceived != std::numeric_limits<uint32_t>::max())
     279    if (networkLoadMetrics.responseHeaderBytesReceived != std::numeric_limits<uint64_t>::max())
    282280        metrics->setResponseHeaderBytesReceived(networkLoadMetrics.responseHeaderBytesReceived);
    283281    if (networkLoadMetrics.responseBodyBytesReceived != std::numeric_limits<uint64_t>::max())
     
    354352        .release();
    355353
    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    }
    358358
    359359    if (auto& certificateInfo = response.certificateInfo()) {
     
    593593}
    594594
    595 void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics, ResourceLoader* resourceLoader)
     595void InspectorNetworkAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, const NetworkLoadMetrics& networkLoadMetrics, ResourceLoader*)
    596596{
    597597    if (m_hiddenRequestIdentifiers.remove(identifier))
     
    599599
    600600    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
    606604        elapsedFinishTime = timestamp();
    607605
  • trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.h

    r278253 r278391  
    150150
    151151    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&);
    153153    Ref<Inspector::Protocol::Network::Metrics> buildObjectForMetrics(const NetworkLoadMetrics&);
    154154    RefPtr<Inspector::Protocol::Network::Response> buildObjectForResourceResponse(const ResourceResponse&, ResourceLoader*);
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r278253 r278391  
    469469    maybeFinishLoadingMultipartContent();
    470470
    471     MonotonicTime responseEndTime = m_timeOfLastDataReceived ? m_timeOfLastDataReceived : MonotonicTime::now();
    472     timing().setResponseEnd(responseEndTime);
    473 
     471    timing().markEndTime();
     472   
    474473    commitIfReady();
    475474    if (!frameLoader())
     
    638637    }
    639638
    640     ASSERT(timing().fetchStart());
     639    ASSERT(timing().startTime());
    641640    if (didReceiveRedirectResponse) {
    642641        // If the redirecting url is not allowed to display content from the target origin,
     
    656655            return completionHandler(WTFMove(newRequest));
    657656        }
    658         timing().addRedirect(redirectResponse.url(), newRequest.url());
    659657    }
    660658
     
    12831281
    12841282    m_applicationCacheHost->mainResourceDataReceived(data, length, -1, false);
    1285     m_timeOfLastDataReceived = MonotonicTime::now();
    12861283
    12871284    if (!isMultipartReplacingLoad())
     
    19151912{
    19161913    m_mainDocumentError = ResourceError();
    1917     timing().markStartTimeAndFetchStart();
     1914    timing().markStartTime();
    19181915    ASSERT(!m_mainResource);
    19191916    ASSERT(!m_loadingMainResource);
     
    19361933
    19371934    ASSERT(timing().startTime());
    1938     ASSERT(timing().fetchStart());
    19391935
    19401936    willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = WTFMove(protectedThis)] (ResourceRequest&& request) mutable {
  • trunk/Source/WebCore/loader/DocumentLoader.h

    r278253 r278391  
    3636#include "DeviceOrientationOrMotionPermissionState.h"
    3737#include "DocumentIdentifier.h"
     38#include "DocumentLoadTiming.h"
    3839#include "DocumentWriter.h"
    3940#include "FrameDestructionObserver.h"
    4041#include "LinkIcon.h"
    41 #include "LoadTiming.h"
    4242#include "NavigationAction.h"
    4343#include "ResourceError.h"
     
    352352    void takeMemoryCacheLoadsForClientNotification(Vector<ResourceRequest>& loads);
    353353
    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 = { }; }
    356357
    357358    // The WebKit layer calls this function when it's ready for the data to actually be added to the document.
     
    597598
    598599    bool m_loadingMainResource { false };
    599     LoadTiming m_loadTiming;
    600 
    601     MonotonicTime m_timeOfLastDataReceived;
     600    DocumentLoadTiming m_loadTiming;
     601
    602602    unsigned long m_identifierForLoadWithoutResourceLoader { 0 };
    603603
  • trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp

    r278253 r278391  
    4646#include "InspectorInstrumentation.h"
    4747#include "LegacySchemeRegistry.h"
    48 #include "LoadTiming.h"
    4948#include "LoaderStrategy.h"
    5049#include "MixedContentChecker.h"
     
    585584    ASSERT(m_options.credentials != FetchOptions::Credentials::Omit);
    586585
    587     LoadTiming loadTiming;
    588     loadTiming.markStartTimeAndFetchStart();
     586    ResourceLoadTiming loadTiming;
     587    loadTiming.markStartTime();
    589588
    590589    // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests.
     
    600599    }
    601600
    602     loadTiming.setResponseEnd(MonotonicTime::now());
     601    loadTiming.markEndTime();
    603602
    604603    if (!error.isNull() && response.httpStatusCode() <= 0) {
     
    655654
    656655    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());
    663657    if (options().initiatorContext == InitiatorContext::Worker)
    664658        finishedTimingForWorkerLoad(resourceTiming);
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r278253 r278391  
    8686#include "InspectorInstrumentation.h"
    8787#include "LinkLoader.h"
    88 #include "LoadTiming.h"
    8988#include "LoaderStrategy.h"
    9089#include "Logging.h"
     
    33043303            if (m_frame.document()->backForwardCacheState() == Document::NotInBackForwardCache) {
    33053304                Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, Event::CanBubble::No, Event::IsCancelable::No));
    3306                 // The DocumentLoader (and thus its LoadTiming) might get destroyed
     3305                // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed
    33073306                // while dispatching the event, so protect it to prevent writing the end
    33083307                // time into freed memory.
    33093308                RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
     3309                auto* timing = documentLoader ? &documentLoader->timing() : nullptr;
    33103310                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();
    33183316            }
    33193317        }
  • trunk/Source/WebCore/loader/ResourceLoader.cpp

    r278185 r278391  
    138138    ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
    139139   
    140     m_loadTiming.markStartTimeAndFetchStart();
    141    
     140    m_loadTiming.markStartTime();
     141
    142142    m_defersLoading = m_options.defersLoadingPolicy == DefersLoadingPolicy::AllowDefersLoading && m_frame->page()->defersLoading();
    143143
  • trunk/Source/WebCore/loader/ResourceLoader.h

    r277767 r278391  
    2929#pragma once
    3030
    31 #include "LoadTiming.h"
    3231#include "ResourceHandleClient.h"
     32#include "ResourceLoadTiming.h"
    3333#include "ResourceLoaderOptions.h"
    3434#include "ResourceLoaderTypes.h"
     
    141141    void willSwitchToSubstituteResource();
    142142
    143     const LoadTiming& loadTiming() { return m_loadTiming; }
     143    const ResourceLoadTiming& loadTiming() { return m_loadTiming; }
    144144
    145145#if PLATFORM(COCOA)
     
    179179    RefPtr<DocumentLoader> m_documentLoader;
    180180    ResourceResponse m_response;
    181     LoadTiming m_loadTiming;
     181    ResourceLoadTiming m_loadTiming;
    182182#if USE(QUICK_LOOK)
    183183    std::unique_ptr<LegacyPreviewLoader> m_previewLoader;
  • trunk/Source/WebCore/loader/ResourceTiming.cpp

    r277767 r278391  
    5858}
    5959
    60 ResourceTiming ResourceTiming::fromCache(const URL& url, const String& initiator, const LoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
     60ResourceTiming ResourceTiming::fromMemoryCache(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
    6161{
    6262    return ResourceTiming(url, initiator, loadTiming, response, securityOrigin);
    6363}
    6464
    65 ResourceTiming ResourceTiming::fromLoad(CachedResource& resource, const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const SecurityOrigin& securityOrigin)
     65ResourceTiming ResourceTiming::fromLoad(CachedResource& resource, const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const SecurityOrigin& securityOrigin)
    6666{
    6767    return ResourceTiming(url, initiator, loadTiming, networkLoadMetrics, resource.response(), securityOrigin);
    6868}
    6969
    70 ResourceTiming ResourceTiming::fromSynchronousLoad(const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
     70ResourceTiming ResourceTiming::fromSynchronousLoad(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
    7171{
    7272    return ResourceTiming(url, initiator, loadTiming, networkLoadMetrics, response, securityOrigin);
    7373}
    7474
    75 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const LoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
     75ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const ResourceLoadTiming& loadTiming, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
    7676    : m_url(url)
    7777    , m_initiator(initiator)
    78     , m_loadTiming(loadTiming)
     78    , m_resourceLoadTiming(loadTiming)
    7979    , m_allowTimingDetails(passesTimingAllowCheck(response, securityOrigin))
    8080{
     
    8282}
    8383
    84 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
     84ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const ResourceLoadTiming& timing, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
    8585    : m_url(url)
    8686    , m_initiator(initiator)
    87     , m_loadTiming(loadTiming)
     87    , m_resourceLoadTiming(timing)
    8888    , m_networkLoadMetrics(networkLoadMetrics)
    8989    , m_allowTimingDetails(passesTimingAllowCheck(response, securityOrigin))
     
    107107ResourceTiming ResourceTiming::isolatedCopy() const
    108108{
    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    );
    110117}
    111118
  • trunk/Source/WebCore/loader/ResourceTiming.h

    r277767 r278391  
    2626#pragma once
    2727
    28 #include "LoadTiming.h"
    2928#include "NetworkLoadMetrics.h"
     29#include "ResourceLoadTiming.h"
    3030#include "ServerTiming.h"
    3131#include <wtf/URL.h>
     
    3636class PerformanceServerTiming;
    3737class ResourceResponse;
     38class ResourceLoadTiming;
    3839class SecurityOrigin;
    3940
     
    4142    WTF_MAKE_FAST_ALLOCATED;
    4243public:
    43     static ResourceTiming fromCache(const URL&, const String& initiator, const LoadTiming&, 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&);
    4647
    4748    const URL& url() const { return m_url; }
    4849    const String& initiator() const { return m_initiator; }
    49     const LoadTiming& loadTiming() const { return m_loadTiming; }
     50    const ResourceLoadTiming& resourceLoadTiming() const { return m_resourceLoadTiming; }
    5051    const NetworkLoadMetrics& networkLoadMetrics() const { return m_networkLoadMetrics; }
    5152    bool allowTimingDetails() const { return m_allowTimingDetails; }
     
    5657
    5758private:
    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)
    6162        : m_url(WTFMove(url))
    6263        , m_initiator(WTFMove(initiator))
    63         , m_loadTiming(WTFMove(loadTiming))
     64        , m_resourceLoadTiming(resourceLoadTiming)
    6465        , m_networkLoadMetrics(WTFMove(networkLoadMetrics))
    6566        , m_allowTimingDetails(allowTimingDetails)
     
    7172    URL m_url;
    7273    String m_initiator;
    73     LoadTiming m_loadTiming;
     74    ResourceLoadTiming m_resourceLoadTiming;
    7475    NetworkLoadMetrics m_networkLoadMetrics;
    7576    bool m_allowTimingDetails { false };
  • trunk/Source/WebCore/loader/ResourceTimingInformation.cpp

    r278119 r278391  
    3333#include "FrameLoader.h"
    3434#include "HTMLFrameOwnerElement.h"
    35 #include "LoadTiming.h"
    3635#include "Performance.h"
    3736#include "ResourceTiming.h"
  • trunk/Source/WebCore/loader/SubresourceLoader.cpp

    r278253 r278391  
    311311            return completionHandler(WTFMove(newRequest));
    312312        }
    313         m_loadTiming.addRedirect(redirectResponse.url(), newRequest.url());
    314313        m_resource->redirectReceived(WTFMove(newRequest), redirectResponse, [this, protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler), continueWillSendRequest = WTFMove(continueWillSendRequest)] (ResourceRequest&& request) mutable {
    315314            RELEASE_LOG_IF_ALLOWED("willSendRequestInternal: resource done notifying clients");
     
    734733    CachedResourceHandle<CachedResource> protectResource(m_resource);
    735734
    736     // FIXME: Remove this with deprecatedNetworkLoadMetrics.
    737     m_loadTiming.setResponseEnd(MonotonicTime::now());
     735    m_loadTiming.markEndTime();
    738736
    739737    if (networkLoadMetrics.isComplete())
     
    744742        // that they populated partial load timing information on the ResourceResponse.
    745743        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 { });
    752745    }
    753746
  • trunk/Source/WebCore/loader/cache/CachedResource.h

    r278253 r278391  
    4646class CachedResourceRequest;
    4747class CookieJar;
    48 class LoadTiming;
    4948class MemoryCache;
    5049class NetworkLoadMetrics;
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r278185 r278391  
    961961    }
    962962
    963     LoadTiming loadTiming;
    964     loadTiming.markStartTimeAndFetchStart();
     963    ResourceLoadTiming loadTiming;
     964    loadTiming.markStartTime();
    965965    InitiatorContext initiatorContext = request.options().initiatorContext;
    966966
     
    10221022                return makeUnexpected(WTFMove(error));
    10231023            logMemoryCacheResourceRequest(&frame, DiagnosticLoggingKeys::memoryCacheEntryDecisionKey(), DiagnosticLoggingKeys::usedKey());
    1024             loadTiming.setResponseEnd(MonotonicTime::now());
     1024            loadTiming.markEndTime();
    10251025
    10261026            memoryCache.resourceAccessed(*resource);
    10271027
    10281028            if (document() && !resource->isLoading()) {
    1029                 auto resourceTiming = ResourceTiming::fromCache(url, request.initiatorName(), loadTiming, resource->response(), *request.origin());
     1029                auto resourceTiming = ResourceTiming::fromMemoryCache(url, request.initiatorName(), loadTiming, resource->response(), *request.origin());
    10301030                if (initiatorContext == InitiatorContext::Worker) {
    10311031                    ASSERT(is<CachedRawResource>(resource.get()));
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r278253 r278391  
    730730{
    731731    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();
    733734        m_performance = Performance::create(document(), timeOrigin);
    734735    }
  • trunk/Source/WebCore/page/Performance.cpp

    r278253 r278391  
    229229}
    230230
    231 void Performance::addNavigationTiming(DocumentLoader& documentLoader, Document& document, CachedResource& resource, const LoadTiming& timing, const NetworkLoadMetrics& metrics)
     231void Performance::addNavigationTiming(DocumentLoader& documentLoader, Document& document, CachedResource& resource, const DocumentLoadTiming& timing, const NetworkLoadMetrics& metrics)
    232232{
    233233    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());
    235235    queueEntry(*m_navigationTiming);
    236236}
  • trunk/Source/WebCore/page/Performance.h

    r278253 r278391  
    5151class CachedResource;
    5252class Document;
     53class DocumentLoadTiming;
    5354class DocumentLoader;
    54 class LoadTiming;
    5555class NetworkLoadMetrics;
    5656class PerformanceUserTiming;
     
    9696    void clearMeasures(const String& measureName);
    9797
    98     void addNavigationTiming(DocumentLoader&, Document&, CachedResource&, const LoadTiming&, const NetworkLoadMetrics&);
     98    void addNavigationTiming(DocumentLoader&, Document&, CachedResource&, const DocumentLoadTiming&, const NetworkLoadMetrics&);
    9999    void addResourceTiming(ResourceTiming&&);
    100100
  • trunk/Source/WebCore/page/PerformanceNavigation.cpp

    r262683 r278391  
    7575        return 0;
    7676
    77     LoadTiming& timing = loader->timing();
    78     if (timing.hasCrossOriginRedirect())
     77    auto* metrics = loader->response().deprecatedNetworkLoadMetricsOrNull();
     78    if (!metrics)
    7979        return 0;
    8080
    81     return timing.redirectCount();
     81    if (metrics->hasCrossOriginRedirect)
     82        return 0;
     83
     84    return metrics->redirectCount;
    8285}
    8386
  • trunk/Source/WebCore/page/PerformanceNavigationTiming.cpp

    r278253 r278391  
    5151}
    5252
    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)
     53PerformanceNavigationTiming::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)
    5657    , m_navigationType(toPerformanceNavigationTimingNavigationType(navigationType)) { }
    5758
    5859PerformanceNavigationTiming::~PerformanceNavigationTiming() = default;
    5960
    60 double PerformanceNavigationTiming::millisecondsSinceOrigin(MonotonicTime time, std::optional<MonotonicTime> timeOrigin) const
     61double PerformanceNavigationTiming::millisecondsSinceOrigin(MonotonicTime time) const
    6162{
    6263    if (!time)
    6364        return 0;
    64     return Performance::reduceTimeResolution(time - (timeOrigin ? *timeOrigin : m_timeOrigin)).milliseconds();
     65    return Performance::reduceTimeResolution(time - m_timeOrigin).milliseconds();
    6566}
    6667
     
    6970    // https://www.w3.org/TR/navigation-timing-2/#dfn-same-origin-check
    7071    return !m_resourceTiming.allowTimingDetails()
    71         || m_resourceTiming.loadTiming().hasCrossOriginRedirect()
    72         || !m_resourceTiming.loadTiming().hasSameOriginAsPreviousDocument();
     72        || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect
     73        || !m_documentLoadTiming.hasSameOriginAsPreviousDocument();
    7374}
    7475
     
    7778    if (sameOriginCheckFails())
    7879        return 0.0;
    79     return millisecondsSinceOrigin(m_resourceTiming.loadTiming().unloadEventStart());
     80    return millisecondsSinceOrigin(m_documentLoadTiming.unloadEventStart());
    8081}
    8182
     
    8485    if (sameOriginCheckFails())
    8586        return 0.0;
    86     return millisecondsSinceOrigin(m_resourceTiming.loadTiming().unloadEventEnd());
     87    return millisecondsSinceOrigin(m_documentLoadTiming.unloadEventEnd());
    8788}
    8889
    8990double PerformanceNavigationTiming::domInteractive() const
    9091{
    91     return millisecondsSinceOrigin(m_documentTiming.domInteractive);
     92    return millisecondsSinceOrigin(m_documentEventTiming.domInteractive);
    9293}
    9394
    9495double PerformanceNavigationTiming::domContentLoadedEventStart() const
    9596{
    96     return millisecondsSinceOrigin(m_documentTiming.domContentLoadedEventStart);
     97    return millisecondsSinceOrigin(m_documentEventTiming.domContentLoadedEventStart);
    9798}
    9899
    99100double PerformanceNavigationTiming::domContentLoadedEventEnd() const
    100101{
    101     return millisecondsSinceOrigin(m_documentTiming.domContentLoadedEventEnd);
     102    return millisecondsSinceOrigin(m_documentEventTiming.domContentLoadedEventEnd);
    102103}
    103104
    104105double PerformanceNavigationTiming::domComplete() const
    105106{
    106     return millisecondsSinceOrigin(m_documentTiming.domComplete);
     107    return millisecondsSinceOrigin(m_documentEventTiming.domComplete);
    107108}
    108109
    109110double PerformanceNavigationTiming::loadEventStart() const
    110111{
    111     return millisecondsSinceOrigin(m_resourceTiming.loadTiming().loadEventStart());
     112    return millisecondsSinceOrigin(m_documentLoadTiming.loadEventStart());
    112113}
    113114
    114115double PerformanceNavigationTiming::loadEventEnd() const
    115116{
    116     return millisecondsSinceOrigin(m_resourceTiming.loadTiming().loadEventEnd());
     117    return millisecondsSinceOrigin(m_documentLoadTiming.loadEventEnd());
    117118}
    118119
     
    127128        return 0;
    128129
    129     if (m_resourceTiming.loadTiming().hasCrossOriginRedirect())
     130    if (m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect)
    130131        return 0;
    131132
    132     return m_resourceTiming.loadTiming().redirectCount();
     133    return m_resourceTiming.networkLoadMetrics().redirectCount;
    133134}
    134135
  • trunk/Source/WebCore/page/PerformanceNavigationTiming.h

    r278253 r278391  
    2626#pragma once
    2727
    28 #include "DocumentTiming.h"
     28#include "DocumentEventTiming.h"
     29#include "DocumentLoadTiming.h"
    2930#include "PerformanceResourceTiming.h"
    3031#include <wtf/MonotonicTime.h>
     
    3536
    3637class CachedResource;
    37 class LoadTiming;
    3838class NetworkLoadMetrics;
    3939class SecurityOrigin;
     
    7070
    7171private:
    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);
    7373
    74     double millisecondsSinceOrigin(MonotonicTime, std::optional<MonotonicTime> timeOrigin = std::nullopt) const;
     74    double millisecondsSinceOrigin(MonotonicTime) const;
    7575    bool sameOriginCheckFails() const;
    7676
    77     DocumentTiming m_documentTiming;
     77    DocumentEventTiming m_documentEventTiming;
     78    DocumentLoadTiming m_documentLoadTiming;
    7879    NavigationType m_navigationType;
    7980};
  • trunk/Source/WebCore/page/PerformanceResourceTiming.cpp

    r277767 r278391  
    3535
    3636#include "Document.h"
     37#include "DocumentLoadTiming.h"
    3738#include "DocumentLoader.h"
    38 #include "LoadTiming.h"
    3939#include "PerformanceServerTiming.h"
    4040#include "ResourceResponse.h"
     
    4444namespace WebCore {
    4545
    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();
     46static 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
     54static 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);
    5463}
    5564
    5665static double entryStartTime(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming)
    5766{
    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());
    6276}
    6377
     
    6781        return entryStartTime(timeOrigin, resourceTiming);
    6882
    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());
    7587}
    7688
     
    103115double PerformanceResourceTiming::redirectStart() const
    104116{
    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);
    109125}
    110126
    111127double PerformanceResourceTiming::redirectEnd() const
    112128{
    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();
    117139}
    118140
    119141double PerformanceResourceTiming::fetchStart() const
    120142{
    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);
    125144}
    126145
    127146double PerformanceResourceTiming::domainLookupStart() const
    128147{
    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)
    133153        return fetchStart();
    134154
    135     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().domainLookupStart);
     155    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupStart);
    136156}
    137157
    138158double PerformanceResourceTiming::domainLookupEnd() const
    139159{
    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)
    144165        return domainLookupStart();
    145166
    146     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().domainLookupEnd);
     167    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupEnd);
    147168}
    148169
    149170double PerformanceResourceTiming::connectStart() const
    150171{
    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)
    155177        return domainLookupEnd();
    156178
    157     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().connectStart);
     179    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectStart);
    158180}
    159181
    160182double PerformanceResourceTiming::connectEnd() const
    161183{
    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)
    166189        return connectStart();
    167190
    168     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().connectEnd);
     191    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectEnd);
    169192}
    170193
    171194double PerformanceResourceTiming::secureConnectionStart() const
    172195{
    173     if (!m_resourceTiming.allowTimingDetails())
     196    if (!m_resourceTiming.allowTimingDetails()
     197        || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect)
    174198        return 0.0;
    175199
     
    177201        return fetchStart();
    178202
    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);
    183207}
    184208
    185209double PerformanceResourceTiming::requestStart() const
    186210{
    187     if (!m_resourceTiming.allowTimingDetails())
     211    if (!m_resourceTiming.allowTimingDetails()
     212        || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect)
    188213        return 0.0;
    189214
    190215    // requestStart is 0 when a network request is not made.
    191     if (m_resourceTiming.networkLoadMetrics().requestStart <= 0_ms)
     216    if (!m_resourceTiming.networkLoadMetrics().requestStart)
    192217        return connectEnd();
    193218
    194     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().requestStart);
     219    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().requestStart);
    195220}
    196221
    197222double PerformanceResourceTiming::responseStart() const
    198223{
    199     if (!m_resourceTiming.allowTimingDetails())
     224    if (!m_resourceTiming.allowTimingDetails()
     225        || m_resourceTiming.networkLoadMetrics().hasCrossOriginRedirect)
    200226        return 0.0;
    201227
    202228    // responseStart is 0 when a network request is not made.
    203     if (m_resourceTiming.networkLoadMetrics().responseStart <= 0_ms)
     229    if (!m_resourceTiming.networkLoadMetrics().responseStart)
    204230        return requestStart();
    205231
    206     return networkLoadTimeToDOMHighResTimeStamp(m_resourceTiming.networkLoadMetrics().responseStart);
     232    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseStart);
    207233}
    208234
     
    210236{
    211237    // 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());
    213239
    214240    if (m_resourceTiming.networkLoadMetrics().isComplete()) {
     241        if (m_resourceTiming.networkLoadMetrics().responseEnd)
     242            return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseEnd);
     243
    215244        // responseEnd is 0 when a network request is not made.
    216245        // 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);
    230254    }
    231255
    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());
    240257}
    241258
  • trunk/Source/WebCore/page/PerformanceResourceTiming.h

    r277767 r278391  
    3232#pragma once
    3333
    34 #include "LoadTiming.h"
    3534#include "NetworkLoadMetrics.h"
    3635#include "PerformanceEntry.h"
     
    7372    ~PerformanceResourceTiming();
    7473
    75     double networkLoadTimeToDOMHighResTimeStamp(Seconds) const;
    76 
    7774    MonotonicTime m_timeOrigin;
    7875    const ResourceTiming m_resourceTiming;
  • trunk/Source/WebCore/page/PerformanceTiming.cpp

    r256632 r278391  
    3333
    3434#include "Document.h"
     35#include "DocumentEventTiming.h"
     36#include "DocumentLoadTiming.h"
    3537#include "DocumentLoader.h"
    36 #include "DocumentTiming.h"
    3738#include "Frame.h"
    3839#include "FrameLoader.h"
    39 #include "LoadTiming.h"
    4040#include "NetworkLoadMetrics.h"
    4141#include "Performance.h"
     
    5151unsigned long long PerformanceTiming::navigationStart() const
    5252{
    53     LoadTiming* timing = loadTiming();
     53    auto* timing = documentLoadTiming();
    5454    if (!timing)
    5555        return 0;
     
    6060unsigned long long PerformanceTiming::unloadEventStart() const
    6161{
    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())
    6771        return 0;
    6872
     
    7276unsigned long long PerformanceTiming::unloadEventEnd() const
    7377{
    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())
    7987        return 0;
    8088
     
    8492unsigned long long PerformanceTiming::redirectStart() const
    8593{
    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);
    94101}
    95102
    96103unsigned long long PerformanceTiming::redirectEnd() const
    97104{
    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);
    106112}
    107113
    108114unsigned long long PerformanceTiming::fetchStart() const
    109115{
    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);
    115121}
    116122
    117123unsigned long long PerformanceTiming::domainLookupStart() const
    118124{
    119     DocumentLoader* loader = documentLoader();
    120     if (!loader)
     125    auto* metrics = networkLoadMetrics();
     126    if (!metrics || !metrics->domainLookupStart)
    121127        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);
    131130}
    132131
    133132unsigned long long PerformanceTiming::domainLookupEnd() const
    134133{
    135     DocumentLoader* loader = documentLoader();
    136     if (!loader)
     134    auto* metrics = networkLoadMetrics();
     135    if (!metrics || !metrics->domainLookupEnd)
    137136        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);
    147139}
    148140
    149141unsigned long long PerformanceTiming::connectStart() const
    150142{
    151     DocumentLoader* loader = documentLoader();
    152     if (!loader)
     143    auto* metrics = networkLoadMetrics();
     144    if (!metrics || !metrics->connectStart
     145        || metrics->domainLookupEnd.secondsSinceEpoch() > metrics->connectStart.secondsSinceEpoch())
    153146        return domainLookupEnd();
    154147
    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);
    171149}
    172150
    173151unsigned long long PerformanceTiming::connectEnd() const
    174152{
    175     DocumentLoader* loader = documentLoader();
    176     if (!loader)
     153    auto* metrics = networkLoadMetrics();
     154    if (!metrics || !metrics->connectEnd)
    177155        return connectStart();
    178156
    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);
    187158}
    188159
    189160unsigned long long PerformanceTiming::secureConnectionStart() const
    190161{
    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);
    201171}
    202172
    203173unsigned long long PerformanceTiming::requestStart() const
    204174{
    205     DocumentLoader* loader = documentLoader();
    206     if (!loader)
     175    auto* metrics = networkLoadMetrics();
     176    if (!metrics || !metrics->requestStart)
    207177        return connectEnd();
    208178   
    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);
    215180}
    216181
    217182unsigned long long PerformanceTiming::responseStart() const
    218183{
    219     DocumentLoader* loader = documentLoader();
    220     if (!loader)
     184    auto* metrics = networkLoadMetrics();
     185    if (!metrics || !metrics->responseStart)
    221186        return requestStart();
    222187
    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);
    229189}
    230190
    231191unsigned long long PerformanceTiming::responseEnd() const
    232192{
    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);
    238198}
    239199
    240200unsigned long long PerformanceTiming::domLoading() const
    241201{
    242     const DocumentTiming* timing = documentTiming();
     202    auto* timing = documentEventTiming();
    243203    if (!timing)
    244204        return fetchStart();
     
    249209unsigned long long PerformanceTiming::domInteractive() const
    250210{
    251     const DocumentTiming* timing = documentTiming();
     211    auto* timing = documentEventTiming();
    252212    if (!timing)
    253213        return 0;
     
    258218unsigned long long PerformanceTiming::domContentLoadedEventStart() const
    259219{
    260     const DocumentTiming* timing = documentTiming();
     220    auto* timing = documentEventTiming();
    261221    if (!timing)
    262222        return 0;
     
    267227unsigned long long PerformanceTiming::domContentLoadedEventEnd() const
    268228{
    269     const DocumentTiming* timing = documentTiming();
     229    auto* timing = documentEventTiming();
    270230    if (!timing)
    271231        return 0;
     
    276236unsigned long long PerformanceTiming::domComplete() const
    277237{
    278     const DocumentTiming* timing = documentTiming();
     238    auto* timing = documentEventTiming();
    279239    if (!timing)
    280240        return 0;
     
    285245unsigned long long PerformanceTiming::loadEventStart() const
    286246{
    287     LoadTiming* timing = loadTiming();
     247    auto* timing = documentLoadTiming();
    288248    if (!timing)
    289249        return 0;
     
    294254unsigned long long PerformanceTiming::loadEventEnd() const
    295255{
    296     LoadTiming* timing = loadTiming();
     256    auto* timing = documentLoadTiming();
    297257    if (!timing)
    298258        return 0;
     
    301261}
    302262
    303 DocumentLoader* PerformanceTiming::documentLoader() const
     263const DocumentLoader* PerformanceTiming::documentLoader() const
    304264{
    305265    auto* frame = this->frame();
     
    310270}
    311271
    312 const DocumentTiming* PerformanceTiming::documentTiming() const
     272const DocumentEventTiming* PerformanceTiming::documentEventTiming() const
    313273{
    314274    auto* frame = this->frame();
     
    316276        return nullptr;
    317277
    318     Document* document = frame->document();
     278    auto* document = frame->document();
    319279    if (!document)
    320280        return nullptr;
    321281
    322     return &document->timing();
    323 }
    324 
    325 LoadTiming* PerformanceTiming::loadTiming() const
    326 {
    327     DocumentLoader* loader = documentLoader();
     282    return &document->eventTiming();
     283}
     284
     285const DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
     286{
     287    auto* loader = documentLoader();
    328288    if (!loader)
    329289        return nullptr;
     
    332292}
    333293
    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());
     294const NetworkLoadMetrics* PerformanceTiming::networkLoadMetrics() const
     295{
     296    auto* loader = documentLoader();
     297    if (!loader)
     298        return nullptr;
     299    return loader->response().deprecatedNetworkLoadMetricsOrNull();
     300}
     301
     302unsigned 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());
    345308    return static_cast<unsigned long long>(reduced.milliseconds());
    346309}
    347310
    348 unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(MonotonicTime timeStamp) const
    349 {
    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 
    361311} // namespace WebCore
  • trunk/Source/WebCore/page/PerformanceTiming.h

    r236917 r278391  
    3939
    4040class DocumentLoader;
     41class DocumentLoadTiming;
    4142class LoadTiming;
    42 struct DocumentTiming;
     43class NetworkLoadMetrics;
     44
     45struct DocumentEventTiming;
    4346
    4447class PerformanceTiming : public RefCounted<PerformanceTiming>, public DOMWindowProperty {
     
    7174    explicit PerformanceTiming(DOMWindow*);
    7275
    73     const DocumentTiming* 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;
    7780    unsigned long long monotonicTimeToIntegerMilliseconds(MonotonicTime) const;
    7881};
  • trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h

    r278340 r278391  
    11/*
    22 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
    3  * Copyright (C) 2014-2017 Apple, Inc. All Rights Reserved.
     3 * Copyright (C) 2014-2021 Apple, Inc. All Rights Reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    2929#include "HTTPHeaderMap.h"
    3030#include <wtf/Box.h>
    31 #include <wtf/Seconds.h>
     31#include <wtf/MonotonicTime.h>
    3232#include <wtf/persistence/PersistentCoder.h>
    3333#include <wtf/text/WTFString.h>
     
    4848OBJC_CLASS NSURLConnection;
    4949OBJC_CLASS NSURLResponse;
    50 OBJC_CLASS NSURLSessionTaskTransactionMetrics;
     50OBJC_CLASS NSURLSessionTaskMetrics;
    5151#endif
    5252
    5353namespace WebCore {
     54
     55class ResourceHandle;
    5456
    5557enum class NetworkLoadPriority : uint8_t {
     
    6264NETWORK_LOAD_METRICS_ADDITIONS_1;
    6365
    64 constexpr Seconds reusedTLSConnectionSentinel { -2 };
     66constexpr MonotonicTime reusedTLSConnectionSentinel { MonotonicTime::fromRawSeconds(-1) };
    6567
    6668class NetworkLoadMetricsWithoutNonTimingData {
    6769    WTF_MAKE_FAST_ALLOCATED(NetworkLoadMetricsWithoutNonTimingData);
    6870public:
    69     NetworkLoadMetricsWithoutNonTimingData() = default;
    70 
    7171    bool isComplete() const { return complete; }
    7272    void markComplete() { complete = true; }
    7373
    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   
    8786    // ALPN Protocol ID: https://w3c.github.io/resource-timing/#bib-RFC7301
    8887    String protocol;
     88
     89    uint16_t redirectCount { 0 };
     90
     91    // FIXME: These could all be made bit fields.
    8992    bool complete { false };
    9093    bool cellular { false };
     
    9396    bool multipath { false };
    9497    bool isReusedConnection { false };
     98    bool hasCrossOriginRedirect { false };
    9599};
    96100
     
    106110        NetworkLoadMetrics copy;
    107111
     112        copy.redirectStart = redirectStart;
    108113        copy.fetchStart = fetchStart;
    109114
     
    118123        copy.complete = complete;
    119124        copy.protocol = protocol.isolatedCopy();
     125        copy.redirectCount = redirectCount;
    120126        copy.cellular = cellular;
    121127        copy.expensive = expensive;
     
    123129        copy.multipath = multipath;
    124130        copy.isReusedConnection = isReusedConnection;
     131        copy.hasCrossOriginRedirect = hasCrossOriginRedirect;
    125132
    126133        copy.remoteAddress = remoteAddress.isolatedCopy();
     
    143150    bool operator==(const NetworkLoadMetrics& other) const
    144151    {
    145         return fetchStart == other.fetchStart
     152        return redirectStart == other.redirectStart
     153            && fetchStart == other.fetchStart
    146154            && domainLookupStart == other.domainLookupStart
    147155            && domainLookupEnd == other.domainLookupEnd
     
    158166            && multipath == other.multipath
    159167            && isReusedConnection == other.isReusedConnection
     168            && hasCrossOriginRedirect == other.hasCrossOriginRedirect
    160169            && protocol == other.protocol
     170            && redirectCount == other.redirectCount
    161171            && remoteAddress == other.remoteAddress
    162172            && connectionIdentifier == other.connectionIdentifier
     
    192202    HTTPHeaderMap requestHeaders;
    193203
    194     uint64_t requestHeaderBytesSent { std::numeric_limits<uint32_t>::max() };
    195     uint64_t responseHeaderBytesReceived { std::numeric_limits<uint32_t>::max() };
     204    uint64_t requestHeaderBytesSent { std::numeric_limits<uint64_t>::max() };
     205    uint64_t responseHeaderBytesReceived { std::numeric_limits<uint64_t>::max() };
    196206    uint64_t requestBodyBytesSent { std::numeric_limits<uint64_t>::max() };
    197207    uint64_t responseBodyBytesReceived { std::numeric_limits<uint64_t>::max() };
     
    200210
    201211#if PLATFORM(COCOA)
    202 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *);
    203 WEBCORE_EXPORT Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskTransactionMetrics *incompleteMetrics);
     212Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *, const ResourceHandle&);
     213WEBCORE_EXPORT Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, bool hasCrossOriginRedirect);
    204214#endif
    205215
     
    209219    static_assert(Encoder::isIPCEncoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder");
    210220
     221    encoder << redirectStart;
    211222    encoder << fetchStart;
    212223    encoder << domainLookupStart;
     
    224235    encoder << multipath;
    225236    encoder << isReusedConnection;
     237    encoder << hasCrossOriginRedirect;
    226238    encoder << protocol;
     239    encoder << redirectCount;
    227240    encoder << remoteAddress;
    228241    encoder << connectionIdentifier;
     
    244257    static_assert(Decoder::isIPCDecoder, "NetworkLoadMetrics should not be stored by the WTF::Persistence::Encoder");
    245258
    246     return decoder.decode(metrics.fetchStart)
     259    return decoder.decode(metrics.redirectStart)
     260        && decoder.decode(metrics.fetchStart)
    247261        && decoder.decode(metrics.domainLookupStart)
    248262        && decoder.decode(metrics.domainLookupEnd)
     
    259273        && decoder.decode(metrics.multipath)
    260274        && decoder.decode(metrics.isReusedConnection)
     275        && decoder.decode(metrics.hasCrossOriginRedirect)
    261276        && decoder.decode(metrics.protocol)
     277        && decoder.decode(metrics.redirectCount)
    262278        && decoder.decode(metrics.remoteAddress)
    263279        && decoder.decode(metrics.connectionIdentifier)
  • trunk/Source/WebCore/platform/network/ResourceHandle.cpp

    r278253 r278391  
    204204    d->m_currentWebChallenge.nullify();
    205205}
    206  
     206
     207bool ResourceHandle::hasCrossOriginRedirect() const
     208{
     209    return d->m_hasCrossOriginRedirect;
     210}
     211
     212void ResourceHandle::setHasCrossOriginRedirect(bool value)
     213{
     214    d->m_hasCrossOriginRedirect = value;
     215}
     216
     217void ResourceHandle::incrementRedirectCount()
     218{
     219    d->m_redirectCount++;
     220}
     221
     222uint16_t ResourceHandle::redirectCount() const
     223{
     224    return d->m_redirectCount;
     225}
     226
     227MonotonicTime ResourceHandle::startTimeBeforeRedirects() const
     228{
     229    return d->m_startTime;
     230}
     231
     232NetworkLoadMetrics* ResourceHandle::networkLoadMetrics()
     233{
     234    return d->m_networkLoadMetrics.get();
     235}
     236
     237void ResourceHandle::setNetworkLoadMetrics(Box<NetworkLoadMetrics>&& metrics)
     238{
     239    d->m_networkLoadMetrics = WTFMove(metrics);
     240}
     241
    207242bool ResourceHandle::shouldContentSniff() const
    208243{
  • trunk/Source/WebCore/platform/network/ResourceHandle.h

    r278253 r278391  
    171171    WEBCORE_EXPORT virtual void cancel();
    172172
     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
    173182    // The client may be 0, in which case no callbacks will be made.
    174183    WEBCORE_EXPORT ResourceHandleClient* client() const;
  • trunk/Source/WebCore/platform/network/ResourceHandleInternal.h

    r264811 r278391  
    3232#include "ResourceRequest.h"
    3333#include "Timer.h"
     34#include <wtf/MonotonicTime.h>
    3435
    3536#if USE(CFURLCONNECTION)
     
    125126   
    126127    bool m_cancelled { false };
    127     unsigned m_redirectCount { 0 };
    128128    unsigned m_authFailureCount { 0 };
    129129    bool m_addedCacheValidationHeaders { false };
    130130    RefPtr<CurlRequest> m_curlRequest;
    131131    RefPtr<SynchronousLoaderMessageQueue> m_messageQueue;
     132#endif
     133    Box<NetworkLoadMetrics> m_networkLoadMetrics;
    132134    MonotonicTime m_startTime;
    133 #endif
     135    uint16_t m_redirectCount { 0 };
     136    bool m_hasCrossOriginRedirect { false };
    134137
    135138#if PLATFORM(COCOA)
  • trunk/Source/WebCore/platform/network/cocoa/NetworkLoadMetrics.mm

    r277767 r278391  
    2727#import "NetworkLoadMetrics.h"
    2828
     29#import "ResourceHandle.h"
    2930#import <pal/spi/cocoa/NSURLConnectionSPI.h>
    3031
    3132namespace WebCore {
    3233
    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)
     34static MonotonicTime dateToMonotonicTime(NSDate *date)
    3435{
     36    if (auto interval = date.timeIntervalSince1970)
     37        return WallTime::fromRawSeconds(interval).approximateMonotonicTime();
     38    return { };
     39}
     40
     41static 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
    3544    auto timing = Box<NetworkLoadMetrics>::create();
    3645
    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);
    4151    if (reusedTLSConnection && [protocol isEqualToString:@"https"])
    4252        timing->secureConnectionStart = reusedTLSConnectionSentinel;
    4353    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;
    4860
    4961    // NOTE: responseEnd is not populated in this code path.
     
    5264}
    5365
    54 Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskTransactionMetrics *incompleteMetrics)
     66Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, bool hasCrossOriginRedirect)
    5567{
     68    NSArray<NSURLSessionTaskTransactionMetrics *> *transactionMetrics = incompleteMetrics.transactionMetrics;
     69    NSURLSessionTaskTransactionMetrics *metrics = transactionMetrics.lastObject;
    5670    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
    6784    );
    6885}
    6986
    70 Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *connection)
     87Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *connection, const ResourceHandle& handle)
    7188{
    7289    NSDictionary *timingData = [connection _timingData];
    73     if (!timingData)
    74         return nullptr;
    7590
    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 { };
    8097    };
    8198
    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()
    93113    );
     114
     115    if (!data->fetchStart)
     116        data->fetchStart = data->redirectStart;
     117
     118    return data;
    94119}
    95120   
  • trunk/Source/WebCore/platform/network/cocoa/WebCoreNSURLSession.mm

    r277958 r278391  
    5151NS_ASSUME_NONNULL_BEGIN
    5252
    53 static NSDate * __nullable networkLoadMetricsDate(Seconds fetchStart, Seconds delta)
    54 {
    55     if (!fetchStart.value())
     53static NSDate * __nullable networkLoadMetricsDate(MonotonicTime time)
     54{
     55    if (!time)
    5656        return nil;
    57     if (delta.value() == -1)
     57    NSTimeInterval value = time.approximateWallTime().secondsSinceEpoch().seconds();
     58    if (value <= 0)
    5859        return nil;
    59     return [NSDate dateWithTimeIntervalSince1970:fetchStart.value() + delta.value()];
     60    return [NSDate dateWithTimeIntervalSince1970:value];
    6061}
    6162
     
    9596- (nullable NSDate *)fetchStartDate
    9697{
    97     return networkLoadMetricsDate(_metrics.fetchStart, Seconds(0));
     98    return networkLoadMetricsDate(_metrics.fetchStart);
    9899}
    99100
     
    101102- (nullable NSDate *)domainLookupStartDate
    102103{
    103     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.domainLookupStart);
     104    return networkLoadMetricsDate(_metrics.domainLookupStart);
    104105}
    105106
     
    107108- (nullable NSDate *)domainLookupEndDate
    108109{
    109     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.domainLookupEnd);
     110    return networkLoadMetricsDate(_metrics.domainLookupEnd);
    110111}
    111112
     
    113114- (nullable NSDate *)connectStartDate
    114115{
    115     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.connectStart);
     116    return networkLoadMetricsDate(_metrics.connectStart);
    116117}
    117118
     
    119120- (nullable NSDate *)secureConnectionStartDate
    120121{
    121     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.secureConnectionStart);
     122    if (_metrics.secureConnectionStart == reusedTLSConnectionSentinel)
     123        return nil;
     124    return networkLoadMetricsDate(_metrics.secureConnectionStart);
    122125}
    123126
     
    125128- (nullable NSDate *)connectEndDate
    126129{
    127     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.connectEnd);
     130    return networkLoadMetricsDate(_metrics.connectEnd);
    128131}
    129132
     
    131134- (nullable NSDate *)requestStartDate
    132135{
    133     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.requestStart);
     136    return networkLoadMetricsDate(_metrics.requestStart);
    134137}
    135138
     
    137140- (nullable NSDate *)responseStartDate
    138141{
    139     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.responseStart);
     142    return networkLoadMetricsDate(_metrics.responseStart);
    140143}
    141144
     
    143146- (nullable NSDate *)responseEndDate
    144147{
    145     return networkLoadMetricsDate(_metrics.fetchStart, _metrics.responseEnd);
     148    return networkLoadMetricsDate(_metrics.responseEnd);
    146149}
    147150
  • trunk/Source/WebCore/platform/network/curl/CurlContext.cpp

    r278253 r278391  
    761761}
    762762
    763 std::optional<NetworkLoadMetrics> CurlHandle::getNetworkLoadMetrics(const WTF::Seconds& domainLookupStart)
     763std::optional<NetworkLoadMetrics> CurlHandle::getNetworkLoadMetrics(MonotonicTime startTime)
    764764{
    765765    double nameLookup = 0.0;
     
    794794    NetworkLoadMetrics networkLoadMetrics;
    795795
    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);
    800800
    801801    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);
    804804    }
    805805
    806806    networkLoadMetrics.requestStart = networkLoadMetrics.connectEnd;
    807     networkLoadMetrics.responseStart = domainLookupStart + Seconds(startTransfer);
     807    networkLoadMetrics.responseStart = startTime + Seconds(startTransfer);
    808808
    809809    if (version == CURL_HTTP_VERSION_1_0)
  • trunk/Source/WebCore/platform/network/curl/CurlContext.h

    r278253 r278391  
    3131
    3232#include <wtf/Lock.h>
     33#include <wtf/MonotonicTime.h>
    3334#include <wtf/NeverDestroyed.h>
    3435#include <wtf/Noncopyable.h>
     
    297298    std::optional<long> getProxyAuthAvail();
    298299    std::optional<long> getHttpVersion();
    299     std::optional<NetworkLoadMetrics> getNetworkLoadMetrics(const WTF::Seconds& domainLookupStart);
     300    std::optional<NetworkLoadMetrics> getNetworkLoadMetrics(MonotonicTime startTime);
    300301    void addExtraNetworkLoadMetrics(NetworkLoadMetrics&);
    301302
  • trunk/Source/WebCore/platform/network/curl/CurlRequest.cpp

    r277920 r278391  
    111111    ASSERT(isMainThread());
    112112
    113     if (std::isnan(m_requestStartTime))
    114         m_requestStartTime = MonotonicTime::now().isolatedCopy();
    115 
    116113    if (m_request.url().isLocalFile())
    117114        invokeDidReceiveResponseForFile(m_request.url());
     
    457454
    458455        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();
    461458            networkLoadMetrics.markComplete();
    462459
     
    727724    ASSERT(m_curlHandle);
    728725
    729     auto domainLookupStart = m_performStartTime - m_requestStartTime;
    730     auto networkLoadMetrics = m_curlHandle->getNetworkLoadMetrics(domainLookupStart);
     726    auto networkLoadMetrics = m_curlHandle->getNetworkLoadMetrics(m_performStartTime);
    731727    if (!networkLoadMetrics)
    732728        return NetworkLoadMetrics();
  • trunk/Source/WebCore/platform/network/curl/CurlRequest.h

    r276211 r278391  
    7777    bool isServerTrustEvaluationDisabled() { return m_shouldDisableServerTrustEvaluation; }
    7878    void disableServerTrustEvaluation() { m_shouldDisableServerTrustEvaluation = true; }
    79     void setStartTime(const MonotonicTime& startTime) { m_requestStartTime = startTime.isolatedCopy(); }
    8079
    8180    void start();
     
    211210    bool m_captureExtraMetrics;
    212211    HTTPHeaderMap m_requestHeaders;
    213     MonotonicTime m_requestStartTime { MonotonicTime::nan() };
    214212    MonotonicTime m_performStartTime;
    215213    size_t m_totalReceivedSize { 0 };
  • trunk/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp

    r278253 r278391  
    8282    }
    8383
    84     d->m_startTime = MonotonicTime::now();
    85 
    8684    d->m_curlRequest = createCurlRequest(WTFMove(request));
    8785
     
    9189    }
    9290
    93     d->m_curlRequest->setStartTime(d->m_startTime);
    9491    d->m_curlRequest->start();
    9592
     
    366363    d->m_curlRequest->setAuthenticationScheme(protectionSpace.authenticationScheme());
    367364    d->m_curlRequest->setUserPass(credential.user(), credential.password());
    368     d->m_curlRequest->setStartTime(d->m_startTime);
    369365    d->m_curlRequest->start();
    370366}
     
    383379    RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(context, request, &client, defersLoading, shouldContentSniff, shouldContentEncodingSniff));
    384380    handle->d->m_messageQueue = &client.messageQueue();
    385     handle->d->m_startTime = MonotonicTime::now();
    386381
    387382    if (request.url().protocolIsData()) {
     
    398393    }
    399394
    400     handle->d->m_curlRequest->setStartTime(handle->d->m_startTime);
    401395    handle->d->m_curlRequest->start();
    402396
     
    486480        newRequest.clearHTTPAuthorization();
    487481        newRequest.clearHTTPOrigin();
    488         d->m_startTime = WTF::MonotonicTime::now();
    489482    }
    490483
     
    517510        d->m_curlRequest->setUserPass(credential->user(), credential->password());
    518511
    519     d->m_curlRequest->setStartTime(d->m_startTime);
    520512    d->m_curlRequest->start();
    521513}
  • trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm

    r277740 r278391  
    268268    [connection() setDelegateQueue:operationQueueForAsyncClients()];
    269269    [connection() start];
     270    d->m_startTime = MonotonicTime::now();
    270271
    271272    LOG(Network, "Handle %p starting connection %p for %@", this, connection(), firstRequest().nsURLRequest(HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody));
  • trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.h

    r278253 r278391  
    2525
    2626#import <dispatch/dispatch.h>
     27#import <wtf/Box.h>
    2728#import <wtf/Function.h>
    2829#import <wtf/Lock.h>
     
    3435
    3536namespace WebCore {
     37class NetworkLoadMetrics;
    3638class ResourceHandle;
    3739class SynchronousLoaderMessageQueue;
  • trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm

    r278253 r278391  
    3535#import "ResourceRequest.h"
    3636#import "ResourceResponse.h"
     37#import "SecurityOrigin.h"
    3738#import "SharedBuffer.h"
    3839#import "SynchronousLoaderClient.h"
     
    148149        if (m_handle->firstRequest().httpContentType().isEmpty())
    149150            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
    150156        m_handle->willSendRequest(WTFMove(redirectRequest), redirectResponse.get(), [self, protectedSelf = WTFMove(protectedSelf)](ResourceRequest&& request) {
    151157            m_requestResult = request.nsURLRequest(HTTPBodyUpdatePolicy::UpdateHTTPBody);
     
    252258            [r _setMIMEType:@"text/html"];
    253259
     260        auto metrics = copyTimingData(connection.get(), *m_handle);
    254261        ResourceResponse resourceResponse(r.get());
    255262        resourceResponse.setSource(ResourceResponse::Source::Network);
    256         resourceResponse.setDeprecatedNetworkLoadMetrics(copyTimingData(connection.get()));
     263        resourceResponse.setDeprecatedNetworkLoadMetrics(Box<NetworkLoadMetrics> { metrics });
     264
     265        m_handle->setNetworkLoadMetrics(WTFMove(metrics));
    257266
    258267        m_handle->didReceiveResponse(WTFMove(resourceResponse), [self, protectedSelf = WTFMove(protectedSelf)] {
     
    316325    LOG(Network, "Handle %p delegate connectionDidFinishLoading:%p", m_handle, connection);
    317326
    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 {
    319330        if (!m_handle || !m_handle->client())
    320331            return;
    321332
    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;
    325338            metrics->markComplete();
    326339            m_handle->client()->didFinishLoading(m_handle, *metrics);
  • trunk/Source/WebCore/platform/network/soup/ResourceRequest.h

    r273236 r278391  
    6666    void setAcceptEncoding(bool acceptEncoding) { m_acceptEncoding = acceptEncoding; }
    6767
     68    void incrementRedirectCount() { m_redirectCount++; }
     69    uint16_t redirectCount() const { return m_redirectCount; }
     70
    6871    void updateSoupMessageBody(SoupMessage*, BlobRegistryImpl&) const;
    6972    void updateSoupMessageHeaders(SoupMessageHeaders*) const;
     
    9093
    9194    bool m_acceptEncoding { true };
     95    uint16_t m_redirectCount { 0 };
    9296};
    9397
     
    105109
    106110    encoder << static_cast<bool>(m_acceptEncoding);
     111    encoder << m_redirectCount;
    107112}
    108113
     
    128133    m_acceptEncoding = acceptEncoding;
    129134
     135    uint16_t redirectCount;
     136    if (!decoder.decode(redirectCount))
     137        return false;
     138    m_redirectCount = redirectCount;
     139
    130140    return true;
    131141}
  • trunk/Source/WebKit/ChangeLog

    r278383 r278391  
     12021-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
    1252021-06-02  Brent Fulgham  <bfulgham@apple.com>
    226
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm

    r278253 r278391  
    459459{
    460460    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());
    461465
    462466    if (redirectResponse.httpStatusCode() == 307 || redirectResponse.httpStatusCode() == 308) {
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r278253 r278391  
    775775    LOG(NetworkSession, "%llu didFinishCollectingMetrics", task.taskIdentifier);
    776776    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        };
    787785
    788786        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);
    793792        if (m.reusedConnection && [m.response.URL.scheme isEqualToString:@"https"])
    794793            networkLoadMetrics.secureConnectionStart = WebCore::reusedTLSConnectionSentinel;
    795794        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);
    801800        networkLoadMetrics.markComplete();
     801        networkLoadMetrics.redirectCount = metrics.redirectCount;
    802802        networkLoadMetrics.protocol = String(m.networkProtocolName);
    803803#if HAVE(CFNETWORK_METRICS_CONNECTION_PROPERTIES)
     
    882882
    883883        NegotiatedLegacyTLS negotiatedLegacyTLS = NegotiatedLegacyTLS::No;
    884         NSURLSessionTaskTransactionMetrics *metrics = dataTask._incompleteTaskMetrics.transactionMetrics.lastObject;
     884        NSURLSessionTaskMetrics *taskMetrics = dataTask._incompleteTaskMetrics;
    885885#if HAVE(TLS_PROTOCOL_VERSION_T)
     886        NSURLSessionTaskTransactionMetrics *metrics = taskMetrics.transactionMetrics.lastObject;
    886887        auto tlsVersion = (tls_protocol_version_t)metrics.negotiatedTLSProtocolVersion.unsignedShortValue;
    887888        if (tlsVersion == tls_protocol_version_TLSv10 || tlsVersion == tls_protocol_version_TLSv11)
    888889            negotiatedLegacyTLS = NegotiatedLegacyTLS::Yes;
    889         UNUSED_PARAM(metrics);
    890890#else // We do not need to check _TLSNegotiatedProtocolVersion if we have metrics.negotiatedTLSProtocolVersion because it works at response time even before rdar://problem/56522601
    891891        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
     
    910910        resourceResponse.disableLazyInitialization();
    911911
    912         resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(metrics));
     912        resourceResponse.setDeprecatedNetworkLoadMetrics(WebCore::copyTimingData(taskMetrics, networkDataTask->networkLoadMetrics().hasCrossOriginRedirect));
    913913
    914914        networkDataTask->didReceiveResponse(WTFMove(resourceResponse), negotiatedLegacyTLS, [completionHandler = makeBlockPtr(completionHandler), taskIdentifier](WebCore::PolicyAction policyAction) {
  • trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp

    r278185 r278391  
    5252    , m_shouldRelaxThirdPartyCookieBlocking(shouldRelaxThirdPartyCookieBlocking)
    5353{
    54     m_startTime = MonotonicTime::now();
    55 
    5654    auto request = requestWithCredentials;
    5755    if (request.url().protocolIsInHTTPFamily()) {
     
    8078        m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
    8179    }
    82     m_curlRequest->setStartTime(m_startTime);
    8380    m_curlRequest->start();
    8481}
     
    312309            m_curlRequest->cancel();
    313310
    314         if (newRequest.url().protocolIsInHTTPFamily() && isCrossOrigin)
    315             m_startTime = MonotonicTime::now();
    316 
    317311        auto requestCopy = newRequest;
    318312        restrictRequestReferrerToOriginIfNeeded(requestCopy);
     
    322316            m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
    323317        }
    324         m_curlRequest->setStartTime(m_startTime);
    325318        m_curlRequest->start();
    326319
     
    443436    if (shouldDisableServerTrustEvaluation)
    444437        m_curlRequest->disableServerTrustEvaluation();
    445     m_curlRequest->setStartTime(m_startTime);
    446438    m_curlRequest->start();
    447439
  • trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h

    r275454 r278391  
    100100    unsigned m_redirectCount { 0 };
    101101    unsigned m_authFailureCount { 0 };
    102     MonotonicTime m_startTime;
    103102
    104103    WebCore::FrameIdentifier m_frameID;
  • trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp

    r278253 r278391  
    6767    if (request.url().protocolIsInHTTPFamily()) {
    6868#if USE(SOUP2)
    69         m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch();
     69        m_networkLoadMetrics.fetchStart = MonotonicTime::now();
     70        m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart;
    7071#endif
    7172        auto url = request.url();
     
    168169    }
    169170
     171    m_networkLoadMetrics.redirectCount = m_currentRequest.redirectCount();
     172
    170173    unsigned messageFlags = SOUP_MESSAGE_NO_REDIRECT;
    171174#if !USE(SOUP2)
     
    268271            auto* metrics = soup_message_get_metrics(m_soupMessage.get());
    269272            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());
    271274            m_networkLoadMetrics.markComplete();
    272275        }
     
    310313            soup_session_send_async(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), m_soupMessage.get(), RunLoopSourcePriority::AsyncIONetwork, m_cancellable.get(),
    311314                reinterpret_cast<GAsyncReadyCallback>(sendRequestCallback), new SendRequestData({ m_soupMessage, WTFMove(protectedThis) }));
    312 #if !USE(SOUP2)
    313315            if (!g_cancellable_is_cancelled(protectCancellable.get()) && !m_networkLoadMetrics.fetchStart) {
     316#if USE(SOUP2)
     317                m_networkLoadMetrics.fetchStart = MonotonicTime::now();
     318#else
    314319                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;
    316324            }
    317 #endif
    318325        }
    319326        return;
     
    472479
    473480#if USE(SOUP2)
    474     m_networkLoadMetrics.responseStart = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
     481    m_networkLoadMetrics.responseStart = MonotonicTime::now();
    475482#endif
    476483
     
    534541{
    535542#if USE(SOUP2)
    536     m_networkLoadMetrics.responseEnd = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
     543    m_networkLoadMetrics.responseEnd = MonotonicTime::now();
    537544    m_networkLoadMetrics.markComplete();
    538545#endif
     
    837844
    838845    static const unsigned maxRedirects = 20;
    839     if (m_redirectCount++ > maxRedirects) {
     846    if (m_currentRequest.redirectCount() > maxRedirects) {
    840847#if USE(SOUP2)
    841848        didFail(ResourceError::transportError(m_currentRequest.url(), SOUP_STATUS_TOO_MANY_REDIRECTS, "Too many redirects"));
     
    845852        return;
    846853    }
     854
     855    m_currentRequest.incrementRedirectCount();
     856    m_networkLoadMetrics.redirectCount = m_currentRequest.redirectCount();
    847857
    848858    ResourceRequest request = m_currentRequest;
     
    851861        redirectedURL.setFragmentIdentifier(request.url().fragmentIdentifier());
    852862    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());
    853866
    854867    // Clear the user agent to ensure a new one is computed.
     
    897910
    898911    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) {
    900913        if (newRequest.isNull() || m_state == State::Canceling)
    901914            return;
     
    903916        auto request = newRequest;
    904917        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 = { };
    911919#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
    917923            applyAuthenticationToRequest(request);
    918924
     
    11131119    auto* metrics = soup_message_get_metrics(m_soupMessage.get());
    11141120    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());
    11161122#endif
    11171123
     
    13621368void NetworkDataTaskSoup::networkEvent(GSocketClientEvent event, GIOStream* stream)
    13631369{
    1364     Seconds deltaTime = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
     1370    auto time = MonotonicTime::now();
    13651371    switch (event) {
    13661372    case G_SOCKET_CLIENT_RESOLVING:
    1367         m_networkLoadMetrics.domainLookupStart = deltaTime;
     1373        m_networkLoadMetrics.domainLookupStart = time;
    13681374        break;
    13691375    case G_SOCKET_CLIENT_RESOLVED:
    1370         m_networkLoadMetrics.domainLookupEnd = deltaTime;
     1376        m_networkLoadMetrics.domainLookupEnd = time;
    13711377        break;
    13721378    case G_SOCKET_CLIENT_CONNECTING:
    1373         m_networkLoadMetrics.connectStart = deltaTime;
     1379        m_networkLoadMetrics.connectStart = time;
    13741380        break;
    13751381    case G_SOCKET_CLIENT_CONNECTED:
     
    13891395        break;
    13901396    case G_SOCKET_CLIENT_TLS_HANDSHAKING:
    1391         m_networkLoadMetrics.secureConnectionStart = deltaTime;
     1397        m_networkLoadMetrics.secureConnectionStart = time;
    13921398        RELEASE_ASSERT(G_IS_TLS_CONNECTION(stream));
    13931399        g_object_set_data(G_OBJECT(stream), "wk-soup-message", m_soupMessage.get());
     
    13971403        break;
    13981404    case G_SOCKET_CLIENT_COMPLETE:
    1399         m_networkLoadMetrics.connectEnd = deltaTime;
     1405        m_networkLoadMetrics.connectEnd = time;
    14001406        break;
    14011407    default:
     
    14601466{
    14611467#if USE(SOUP2)
    1462     m_networkLoadMetrics.requestStart = MonotonicTime::now().secondsSinceEpoch() - m_networkLoadMetrics.fetchStart;
     1468    m_networkLoadMetrics.requestStart = MonotonicTime::now();
    14631469#else
    14641470    auto* metrics = soup_message_get_metrics(m_soupMessage.get());
     
    14701476    auto requestStart = Seconds::fromMicroseconds(soup_message_metrics_get_request_start(metrics));
    14711477
    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());
    14781484#endif
    14791485}
     
    14941500    m_networkLoadMetrics = { };
    14951501#if USE(SOUP2)
    1496     m_networkLoadMetrics.fetchStart = MonotonicTime::now().secondsSinceEpoch();
     1502    m_networkLoadMetrics.fetchStart = MonotonicTime::now();
    14971503#else
    14981504    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());
    15001506    m_currentRequest.updateSoupMessageBody(m_soupMessage.get(), m_session->blobRegistry());
    15011507#endif
     1508    m_networkLoadMetrics.redirectStart = m_networkLoadMetrics.fetchStart;
    15021509}
    15031510
  • trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h

    r278253 r278391  
    196196    CString m_sniffedContentType;
    197197    Vector<char> m_readBuffer;
    198     unsigned m_redirectCount { 0 };
    199198    uint64_t m_bodyDataTotalBytesSent { 0 };
    200199    GRefPtr<GFile> m_downloadDestinationFile;
Note: See TracChangeset for help on using the changeset viewer.