1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #include "core/timing/PerformanceResourceTiming.h"
34
35 #include "core/dom/Document.h"
36 #include "core/loader/DocumentLoadTiming.h"
37 #include "core/loader/DocumentLoader.h"
38 #include "core/timing/ResourceTimingInfo.h"
39 #include "platform/network/ResourceRequest.h"
40 #include "platform/network/ResourceResponse.h"
41
42 namespace blink {
43
monotonicTimeToDocumentMilliseconds(Document * document,double seconds)44 static double monotonicTimeToDocumentMilliseconds(Document* document, double seconds)
45 {
46 ASSERT(seconds >= 0.0);
47 return document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(seconds) * 1000.0;
48 }
49
PerformanceResourceTiming(const ResourceTimingInfo & info,Document * requestingDocument,double startTime,double lastRedirectEndTime,bool allowTimingDetails,bool allowRedirectDetails)50 PerformanceResourceTiming::PerformanceResourceTiming(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool allowTimingDetails, bool allowRedirectDetails)
51 : PerformanceEntry(info.initialRequest().url().string(), "resource", monotonicTimeToDocumentMilliseconds(requestingDocument, startTime), monotonicTimeToDocumentMilliseconds(requestingDocument, info.loadFinishTime()))
52 , m_initiatorType(info.initiatorType())
53 , m_timing(info.finalResponse().resourceLoadTiming())
54 , m_lastRedirectEndTime(lastRedirectEndTime)
55 , m_finishTime(info.loadFinishTime())
56 , m_didReuseConnection(info.finalResponse().connectionReused())
57 , m_allowTimingDetails(allowTimingDetails)
58 , m_allowRedirectDetails(allowRedirectDetails)
59 , m_requestingDocument(requestingDocument)
60 {
61 }
62
~PerformanceResourceTiming()63 PerformanceResourceTiming::~PerformanceResourceTiming()
64 {
65 }
66
initiatorType() const67 AtomicString PerformanceResourceTiming::initiatorType() const
68 {
69 return m_initiatorType;
70 }
71
redirectStart() const72 double PerformanceResourceTiming::redirectStart() const
73 {
74 if (!m_lastRedirectEndTime || !m_allowRedirectDetails)
75 return 0.0;
76
77 return PerformanceEntry::startTime();
78 }
79
redirectEnd() const80 double PerformanceResourceTiming::redirectEnd() const
81 {
82 if (!m_lastRedirectEndTime || !m_allowRedirectDetails)
83 return 0.0;
84
85 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_lastRedirectEndTime);
86 }
87
fetchStart() const88 double PerformanceResourceTiming::fetchStart() const
89 {
90 if (m_lastRedirectEndTime) {
91 // FIXME: ASSERT(m_timing) should be in constructor once timeticks of
92 // AppCache is exposed from chrome network stack, crbug/251100
93 ASSERT(m_timing);
94 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->requestTime);
95 }
96
97 return PerformanceEntry::startTime();
98 }
99
domainLookupStart() const100 double PerformanceResourceTiming::domainLookupStart() const
101 {
102 if (!m_allowTimingDetails)
103 return 0.0;
104
105 if (!m_timing || m_timing->dnsStart == 0.0)
106 return fetchStart();
107
108 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->dnsStart);
109 }
110
domainLookupEnd() const111 double PerformanceResourceTiming::domainLookupEnd() const
112 {
113 if (!m_allowTimingDetails)
114 return 0.0;
115
116 if (!m_timing || m_timing->dnsEnd == 0.0)
117 return domainLookupStart();
118
119 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->dnsEnd);
120 }
121
connectStart() const122 double PerformanceResourceTiming::connectStart() const
123 {
124 if (!m_allowTimingDetails)
125 return 0.0;
126
127 // connectStart will be zero when a network request is not made.
128 if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection)
129 return domainLookupEnd();
130
131 // connectStart includes any DNS time, so we may need to trim that off.
132 double connectStart = m_timing->connectStart;
133 if (m_timing->dnsEnd > 0.0)
134 connectStart = m_timing->dnsEnd;
135
136 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), connectStart);
137 }
138
connectEnd() const139 double PerformanceResourceTiming::connectEnd() const
140 {
141 if (!m_allowTimingDetails)
142 return 0.0;
143
144 // connectStart will be zero when a network request is not made.
145 if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection)
146 return connectStart();
147
148 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->connectEnd);
149 }
150
secureConnectionStart() const151 double PerformanceResourceTiming::secureConnectionStart() const
152 {
153 if (!m_allowTimingDetails)
154 return 0.0;
155
156 if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotiated.
157 return 0.0;
158
159 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->sslStart);
160 }
161
requestStart() const162 double PerformanceResourceTiming::requestStart() const
163 {
164 if (!m_allowTimingDetails)
165 return 0.0;
166
167 if (!m_timing)
168 return connectEnd();
169
170 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->sendStart);
171 }
172
responseStart() const173 double PerformanceResourceTiming::responseStart() const
174 {
175 if (!m_allowTimingDetails)
176 return 0.0;
177
178 if (!m_timing)
179 return requestStart();
180
181 // FIXME: This number isn't exactly correct. See the notes in PerformanceTiming::responseStart().
182 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->receiveHeadersEnd);
183 }
184
responseEnd() const185 double PerformanceResourceTiming::responseEnd() const
186 {
187 if (!m_finishTime)
188 return responseStart();
189
190 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_finishTime);
191 }
192
trace(Visitor * visitor)193 void PerformanceResourceTiming::trace(Visitor* visitor)
194 {
195 visitor->trace(m_requestingDocument);
196 PerformanceEntry::trace(visitor);
197 }
198
199 } // namespace blink
200