OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | 3 * Copyright (C) 2012 Intel Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 18 matching lines...) Expand all Loading... |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #include "config.h" | 32 #include "config.h" |
33 #include "core/page/PerformanceResourceTiming.h" | 33 #include "core/page/PerformanceResourceTiming.h" |
34 | 34 |
35 #include <wtf/Vector.h> | 35 #include <wtf/Vector.h> |
36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
37 #include "core/loader/DocumentLoadTiming.h" | 37 #include "core/loader/DocumentLoadTiming.h" |
38 #include "core/loader/DocumentLoader.h" | 38 #include "core/loader/DocumentLoader.h" |
| 39 #include "core/page/ResourceTimingInfo.h" |
39 #include "core/platform/network/ResourceRequest.h" | 40 #include "core/platform/network/ResourceRequest.h" |
40 #include "core/platform/network/ResourceResponse.h" | 41 #include "core/platform/network/ResourceResponse.h" |
41 #include "weborigin/SecurityOrigin.h" | |
42 | 42 |
43 namespace WebCore { | 43 namespace WebCore { |
44 | 44 |
45 static double monotonicTimeToDocumentMilliseconds(Document* document, double sec
onds) | 45 static double monotonicTimeToDocumentMilliseconds(Document* document, double sec
onds) |
46 { | 46 { |
47 ASSERT(seconds >= 0.0); | 47 ASSERT(seconds >= 0.0); |
48 return document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(se
conds) * 1000.0; | 48 return document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(se
conds) * 1000.0; |
49 } | 49 } |
50 | 50 |
51 static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
equestingDocument) | 51 PerformanceResourceTiming::PerformanceResourceTiming(const ResourceTimingInfo& i
nfo, Document* requestingDocument, double startTime, double lastRedirectEndTime,
bool allowTimingDetails, bool allowRedirectDetails) |
52 { | 52 : PerformanceEntry(info.initialRequest().url().string(), "resource", monoton
icTimeToDocumentMilliseconds(requestingDocument, startTime), monotonicTimeToDocu
mentMilliseconds(requestingDocument, info.loadFinishTime())) |
53 AtomicallyInitializedStatic(AtomicString&, timingAllowOrigin = *new AtomicSt
ring("timing-allow-origin")); | 53 , m_initiatorType(info.initiatorType()) |
54 | 54 , m_timing(info.finalResponse().resourceLoadTiming()) |
55 RefPtr<SecurityOrigin> resourceOrigin = SecurityOrigin::create(response.url(
)); | 55 , m_lastRedirectEndTime(lastRedirectEndTime) |
56 if (resourceOrigin->isSameSchemeHostPort(requestingDocument->securityOrigin(
))) | 56 , m_finishTime(info.loadFinishTime()) |
57 return true; | 57 , m_didReuseConnection(info.finalResponse().connectionReused()) |
58 | 58 , m_allowTimingDetails(allowTimingDetails) |
59 const String& timingAllowOriginString = response.httpHeaderField(timingAllow
Origin); | 59 , m_allowRedirectDetails(allowRedirectDetails) |
60 if (timingAllowOriginString.isEmpty() || equalIgnoringCase(timingAllowOrigin
String, "null")) | |
61 return false; | |
62 | |
63 if (timingAllowOriginString == "*") | |
64 return true; | |
65 | |
66 const String& securityOrigin = requestingDocument->securityOrigin()->toStrin
g(); | |
67 Vector<String> timingAllowOrigins; | |
68 timingAllowOriginString.split(" ", timingAllowOrigins); | |
69 for (size_t i = 0; i < timingAllowOrigins.size(); ++i) | |
70 if (timingAllowOrigins[i] == securityOrigin) | |
71 return true; | |
72 | |
73 return false; | |
74 } | |
75 | |
76 PerformanceResourceTiming::PerformanceResourceTiming(const AtomicString& initiat
orType, const ResourceRequest& request, const ResourceResponse& response, double
initiationTime, double finishTime, Document* requestingDocument) | |
77 : PerformanceEntry(request.url().string(), "resource", monotonicTimeToDocume
ntMilliseconds(requestingDocument, initiationTime), monotonicTimeToDocumentMilli
seconds(requestingDocument, finishTime)) | |
78 , m_initiatorType(initiatorType) | |
79 , m_timing(response.resourceLoadTiming()) | |
80 , m_finishTime(finishTime) | |
81 , m_didReuseConnection(response.connectionReused()) | |
82 , m_shouldReportDetails(passesTimingAllowCheck(response, requestingDocument)
) | |
83 , m_requestingDocument(requestingDocument) | 60 , m_requestingDocument(requestingDocument) |
84 { | 61 { |
| 62 ASSERT(m_timing); |
85 ScriptWrappable::init(this); | 63 ScriptWrappable::init(this); |
86 } | 64 } |
87 | 65 |
88 PerformanceResourceTiming::~PerformanceResourceTiming() | 66 PerformanceResourceTiming::~PerformanceResourceTiming() |
89 { | 67 { |
90 } | 68 } |
91 | 69 |
92 AtomicString PerformanceResourceTiming::initiatorType() const | 70 AtomicString PerformanceResourceTiming::initiatorType() const |
93 { | 71 { |
94 return m_initiatorType; | 72 return m_initiatorType; |
95 } | 73 } |
96 | 74 |
97 double PerformanceResourceTiming::redirectStart() const | 75 double PerformanceResourceTiming::redirectStart() const |
98 { | 76 { |
99 // FIXME: Need to track and report redirects for resources. | 77 if (!m_lastRedirectEndTime || !m_allowRedirectDetails) |
100 if (!m_shouldReportDetails) | |
101 return 0.0; | 78 return 0.0; |
102 return 0; | 79 |
| 80 return PerformanceEntry::startTime(); |
103 } | 81 } |
104 | 82 |
105 double PerformanceResourceTiming::redirectEnd() const | 83 double PerformanceResourceTiming::redirectEnd() const |
106 { | 84 { |
107 if (!m_shouldReportDetails) | 85 if (!m_lastRedirectEndTime || !m_allowRedirectDetails) |
108 return 0.0; | 86 return 0.0; |
109 return 0; | 87 |
| 88 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_las
tRedirectEndTime); |
110 } | 89 } |
111 | 90 |
112 double PerformanceResourceTiming::fetchStart() const | 91 double PerformanceResourceTiming::fetchStart() const |
113 { | 92 { |
114 // FIXME: This should be different depending on redirects. | 93 if (m_lastRedirectEndTime) |
115 return (startTime()); | 94 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m
_timing->requestTime); |
| 95 |
| 96 return PerformanceEntry::startTime(); |
116 } | 97 } |
117 | 98 |
118 double PerformanceResourceTiming::domainLookupStart() const | 99 double PerformanceResourceTiming::domainLookupStart() const |
119 { | 100 { |
120 if (!m_shouldReportDetails) | 101 if (!m_allowTimingDetails) |
121 return 0.0; | 102 return 0.0; |
122 | 103 |
123 if (!m_timing || m_timing->dnsStart == 0.0) | 104 if (!m_timing || m_timing->dnsStart == 0.0) |
124 return fetchStart(); | 105 return fetchStart(); |
125 | 106 |
126 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsStart); | 107 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsStart); |
127 } | 108 } |
128 | 109 |
129 double PerformanceResourceTiming::domainLookupEnd() const | 110 double PerformanceResourceTiming::domainLookupEnd() const |
130 { | 111 { |
131 if (!m_shouldReportDetails) | 112 if (!m_allowTimingDetails) |
132 return 0.0; | 113 return 0.0; |
133 | 114 |
134 if (!m_timing || m_timing->dnsEnd == 0.0) | 115 if (!m_timing || m_timing->dnsEnd == 0.0) |
135 return domainLookupStart(); | 116 return domainLookupStart(); |
136 | 117 |
137 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsEnd); | 118 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsEnd); |
138 } | 119 } |
139 | 120 |
140 double PerformanceResourceTiming::connectStart() const | 121 double PerformanceResourceTiming::connectStart() const |
141 { | 122 { |
142 if (!m_shouldReportDetails) | 123 if (!m_allowTimingDetails) |
143 return 0.0; | 124 return 0.0; |
144 | 125 |
145 // connectStart will be zero when a network request is not made. | 126 // connectStart will be zero when a network request is not made. |
146 if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection) | 127 if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection) |
147 return domainLookupEnd(); | 128 return domainLookupEnd(); |
148 | 129 |
149 // connectStart includes any DNS time, so we may need to trim that off. | 130 // connectStart includes any DNS time, so we may need to trim that off. |
150 double connectStart = m_timing->connectStart; | 131 double connectStart = m_timing->connectStart; |
151 if (m_timing->dnsEnd > 0.0) | 132 if (m_timing->dnsEnd > 0.0) |
152 connectStart = m_timing->dnsEnd; | 133 connectStart = m_timing->dnsEnd; |
153 | 134 |
154 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), conne
ctStart); | 135 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), conne
ctStart); |
155 } | 136 } |
156 | 137 |
157 double PerformanceResourceTiming::connectEnd() const | 138 double PerformanceResourceTiming::connectEnd() const |
158 { | 139 { |
159 if (!m_shouldReportDetails) | 140 if (!m_allowTimingDetails) |
160 return 0.0; | 141 return 0.0; |
161 | 142 |
162 // connectStart will be zero when a network request is not made. | 143 // connectStart will be zero when a network request is not made. |
163 if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection) | 144 if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection) |
164 return connectStart(); | 145 return connectStart(); |
165 | 146 |
166 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->connectEnd); | 147 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->connectEnd); |
167 } | 148 } |
168 | 149 |
169 double PerformanceResourceTiming::secureConnectionStart() const | 150 double PerformanceResourceTiming::secureConnectionStart() const |
170 { | 151 { |
171 if (!m_shouldReportDetails) | 152 if (!m_allowTimingDetails) |
172 return 0.0; | 153 return 0.0; |
173 | 154 |
174 if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotia
ted. | 155 if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotia
ted. |
175 return 0.0; | 156 return 0.0; |
176 | 157 |
177 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sslStart); | 158 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sslStart); |
178 } | 159 } |
179 | 160 |
180 double PerformanceResourceTiming::requestStart() const | 161 double PerformanceResourceTiming::requestStart() const |
181 { | 162 { |
182 if (!m_shouldReportDetails) | 163 if (!m_allowTimingDetails) |
183 return 0.0; | 164 return 0.0; |
184 | 165 |
185 if (!m_timing) | 166 if (!m_timing) |
186 return connectEnd(); | 167 return connectEnd(); |
187 | 168 |
188 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sendStart); | 169 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sendStart); |
189 } | 170 } |
190 | 171 |
191 double PerformanceResourceTiming::responseStart() const | 172 double PerformanceResourceTiming::responseStart() const |
192 { | 173 { |
193 if (!m_shouldReportDetails) | 174 if (!m_allowTimingDetails) |
194 return 0.0; | 175 return 0.0; |
195 | 176 |
196 if (!m_timing) | 177 if (!m_timing) |
197 return requestStart(); | 178 return requestStart(); |
198 | 179 |
199 // FIXME: This number isn't exactly correct. See the notes in PerformanceTim
ing::responseStart(). | 180 // FIXME: This number isn't exactly correct. See the notes in PerformanceTim
ing::responseStart(). |
200 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->receiveHeadersEnd); | 181 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->receiveHeadersEnd); |
201 } | 182 } |
202 | 183 |
203 double PerformanceResourceTiming::responseEnd() const | 184 double PerformanceResourceTiming::responseEnd() const |
204 { | 185 { |
205 if (!m_finishTime) | 186 if (!m_finishTime) |
206 return responseStart(); | 187 return responseStart(); |
207 | 188 |
208 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_fin
ishTime); | 189 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_fin
ishTime); |
209 } | 190 } |
210 | 191 |
211 } // namespace WebCore | 192 } // namespace WebCore |
OLD | NEW |