| 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 |