| 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" | |
| 40 #include "core/platform/network/ResourceRequest.h" | 39 #include "core/platform/network/ResourceRequest.h" |
| 41 #include "core/platform/network/ResourceResponse.h" | 40 #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 PerformanceResourceTiming::PerformanceResourceTiming(const ResourceTimingInfo& i
nfo, Document* requestingDocument, double startTime, double lastRedirectEndTime,
bool allowTimingDetails, bool allowRedirectDetails) | 51 static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
equestingDocument) |
| 52 : PerformanceEntry(info.initialRequest().url().string(), "resource", monoton
icTimeToDocumentMilliseconds(requestingDocument, startTime), monotonicTimeToDocu
mentMilliseconds(requestingDocument, info.loadFinishTime())) | 52 { |
| 53 , m_initiatorType(info.initiatorType()) | 53 AtomicallyInitializedStatic(AtomicString&, timingAllowOrigin = *new AtomicSt
ring("timing-allow-origin")); |
| 54 , m_timing(info.finalResponse().resourceLoadTiming()) | 54 |
| 55 , m_lastRedirectEndTime(lastRedirectEndTime) | 55 RefPtr<SecurityOrigin> resourceOrigin = SecurityOrigin::create(response.url(
)); |
| 56 , m_finishTime(info.loadFinishTime()) | 56 if (resourceOrigin->isSameSchemeHostPort(requestingDocument->securityOrigin(
))) |
| 57 , m_didReuseConnection(info.finalResponse().connectionReused()) | 57 return true; |
| 58 , m_allowTimingDetails(allowTimingDetails) | 58 |
| 59 , m_allowRedirectDetails(allowRedirectDetails) | 59 const String& timingAllowOriginString = response.httpHeaderField(timingAllow
Origin); |
| 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)
) |
| 60 , m_requestingDocument(requestingDocument) | 83 , m_requestingDocument(requestingDocument) |
| 61 { | 84 { |
| 62 ASSERT(m_timing); | |
| 63 ScriptWrappable::init(this); | 85 ScriptWrappable::init(this); |
| 64 } | 86 } |
| 65 | 87 |
| 66 PerformanceResourceTiming::~PerformanceResourceTiming() | 88 PerformanceResourceTiming::~PerformanceResourceTiming() |
| 67 { | 89 { |
| 68 } | 90 } |
| 69 | 91 |
| 70 AtomicString PerformanceResourceTiming::initiatorType() const | 92 AtomicString PerformanceResourceTiming::initiatorType() const |
| 71 { | 93 { |
| 72 return m_initiatorType; | 94 return m_initiatorType; |
| 73 } | 95 } |
| 74 | 96 |
| 75 double PerformanceResourceTiming::redirectStart() const | 97 double PerformanceResourceTiming::redirectStart() const |
| 76 { | 98 { |
| 77 if (!m_lastRedirectEndTime || !m_allowRedirectDetails) | 99 // FIXME: Need to track and report redirects for resources. |
| 100 if (!m_shouldReportDetails) |
| 78 return 0.0; | 101 return 0.0; |
| 79 | 102 return 0; |
| 80 return PerformanceEntry::startTime(); | |
| 81 } | 103 } |
| 82 | 104 |
| 83 double PerformanceResourceTiming::redirectEnd() const | 105 double PerformanceResourceTiming::redirectEnd() const |
| 84 { | 106 { |
| 85 if (!m_lastRedirectEndTime || !m_allowRedirectDetails) | 107 if (!m_shouldReportDetails) |
| 86 return 0.0; | 108 return 0.0; |
| 87 | 109 return 0; |
| 88 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_las
tRedirectEndTime); | |
| 89 } | 110 } |
| 90 | 111 |
| 91 double PerformanceResourceTiming::fetchStart() const | 112 double PerformanceResourceTiming::fetchStart() const |
| 92 { | 113 { |
| 93 if (m_lastRedirectEndTime) | 114 // FIXME: This should be different depending on redirects. |
| 94 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m
_timing->requestTime); | 115 return (startTime()); |
| 95 | |
| 96 return PerformanceEntry::startTime(); | |
| 97 } | 116 } |
| 98 | 117 |
| 99 double PerformanceResourceTiming::domainLookupStart() const | 118 double PerformanceResourceTiming::domainLookupStart() const |
| 100 { | 119 { |
| 101 if (!m_allowTimingDetails) | 120 if (!m_shouldReportDetails) |
| 102 return 0.0; | 121 return 0.0; |
| 103 | 122 |
| 104 if (!m_timing || m_timing->dnsStart == 0.0) | 123 if (!m_timing || m_timing->dnsStart == 0.0) |
| 105 return fetchStart(); | 124 return fetchStart(); |
| 106 | 125 |
| 107 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsStart); | 126 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsStart); |
| 108 } | 127 } |
| 109 | 128 |
| 110 double PerformanceResourceTiming::domainLookupEnd() const | 129 double PerformanceResourceTiming::domainLookupEnd() const |
| 111 { | 130 { |
| 112 if (!m_allowTimingDetails) | 131 if (!m_shouldReportDetails) |
| 113 return 0.0; | 132 return 0.0; |
| 114 | 133 |
| 115 if (!m_timing || m_timing->dnsEnd == 0.0) | 134 if (!m_timing || m_timing->dnsEnd == 0.0) |
| 116 return domainLookupStart(); | 135 return domainLookupStart(); |
| 117 | 136 |
| 118 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsEnd); | 137 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->dnsEnd); |
| 119 } | 138 } |
| 120 | 139 |
| 121 double PerformanceResourceTiming::connectStart() const | 140 double PerformanceResourceTiming::connectStart() const |
| 122 { | 141 { |
| 123 if (!m_allowTimingDetails) | 142 if (!m_shouldReportDetails) |
| 124 return 0.0; | 143 return 0.0; |
| 125 | 144 |
| 126 // connectStart will be zero when a network request is not made. | 145 // connectStart will be zero when a network request is not made. |
| 127 if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection) | 146 if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection) |
| 128 return domainLookupEnd(); | 147 return domainLookupEnd(); |
| 129 | 148 |
| 130 // connectStart includes any DNS time, so we may need to trim that off. | 149 // connectStart includes any DNS time, so we may need to trim that off. |
| 131 double connectStart = m_timing->connectStart; | 150 double connectStart = m_timing->connectStart; |
| 132 if (m_timing->dnsEnd > 0.0) | 151 if (m_timing->dnsEnd > 0.0) |
| 133 connectStart = m_timing->dnsEnd; | 152 connectStart = m_timing->dnsEnd; |
| 134 | 153 |
| 135 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), conne
ctStart); | 154 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), conne
ctStart); |
| 136 } | 155 } |
| 137 | 156 |
| 138 double PerformanceResourceTiming::connectEnd() const | 157 double PerformanceResourceTiming::connectEnd() const |
| 139 { | 158 { |
| 140 if (!m_allowTimingDetails) | 159 if (!m_shouldReportDetails) |
| 141 return 0.0; | 160 return 0.0; |
| 142 | 161 |
| 143 // connectStart will be zero when a network request is not made. | 162 // connectStart will be zero when a network request is not made. |
| 144 if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection) | 163 if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection) |
| 145 return connectStart(); | 164 return connectStart(); |
| 146 | 165 |
| 147 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->connectEnd); | 166 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->connectEnd); |
| 148 } | 167 } |
| 149 | 168 |
| 150 double PerformanceResourceTiming::secureConnectionStart() const | 169 double PerformanceResourceTiming::secureConnectionStart() const |
| 151 { | 170 { |
| 152 if (!m_allowTimingDetails) | 171 if (!m_shouldReportDetails) |
| 153 return 0.0; | 172 return 0.0; |
| 154 | 173 |
| 155 if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotia
ted. | 174 if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotia
ted. |
| 156 return 0.0; | 175 return 0.0; |
| 157 | 176 |
| 158 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sslStart); | 177 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sslStart); |
| 159 } | 178 } |
| 160 | 179 |
| 161 double PerformanceResourceTiming::requestStart() const | 180 double PerformanceResourceTiming::requestStart() const |
| 162 { | 181 { |
| 163 if (!m_allowTimingDetails) | 182 if (!m_shouldReportDetails) |
| 164 return 0.0; | 183 return 0.0; |
| 165 | 184 |
| 166 if (!m_timing) | 185 if (!m_timing) |
| 167 return connectEnd(); | 186 return connectEnd(); |
| 168 | 187 |
| 169 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sendStart); | 188 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->sendStart); |
| 170 } | 189 } |
| 171 | 190 |
| 172 double PerformanceResourceTiming::responseStart() const | 191 double PerformanceResourceTiming::responseStart() const |
| 173 { | 192 { |
| 174 if (!m_allowTimingDetails) | 193 if (!m_shouldReportDetails) |
| 175 return 0.0; | 194 return 0.0; |
| 176 | 195 |
| 177 if (!m_timing) | 196 if (!m_timing) |
| 178 return requestStart(); | 197 return requestStart(); |
| 179 | 198 |
| 180 // FIXME: This number isn't exactly correct. See the notes in PerformanceTim
ing::responseStart(). | 199 // FIXME: This number isn't exactly correct. See the notes in PerformanceTim
ing::responseStart(). |
| 181 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->receiveHeadersEnd); | 200 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_tim
ing->receiveHeadersEnd); |
| 182 } | 201 } |
| 183 | 202 |
| 184 double PerformanceResourceTiming::responseEnd() const | 203 double PerformanceResourceTiming::responseEnd() const |
| 185 { | 204 { |
| 186 if (!m_finishTime) | 205 if (!m_finishTime) |
| 187 return responseStart(); | 206 return responseStart(); |
| 188 | 207 |
| 189 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_fin
ishTime); | 208 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_fin
ishTime); |
| 190 } | 209 } |
| 191 | 210 |
| 192 } // namespace WebCore | 211 } // namespace WebCore |
| OLD | NEW |