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 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 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 63 PerformanceResourceTiming::~PerformanceResourceTiming() 64 { 65 } 66 67 AtomicString PerformanceResourceTiming::initiatorType() const 68 { 69 return m_initiatorType; 70 } 71 72 double PerformanceResourceTiming::redirectStart() const 73 { 74 if (!m_lastRedirectEndTime || !m_allowRedirectDetails) 75 return 0.0; 76 77 return PerformanceEntry::startTime(); 78 } 79 80 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 88 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 100 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 111 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 122 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 139 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 151 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 162 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 173 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 185 double PerformanceResourceTiming::responseEnd() const 186 { 187 if (!m_finishTime) 188 return responseStart(); 189 190 return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_finishTime); 191 } 192 193 void PerformanceResourceTiming::trace(Visitor* visitor) 194 { 195 visitor->trace(m_requestingDocument); 196 PerformanceEntry::trace(visitor); 197 } 198 199 } // namespace blink 200