1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_PerformanceResourceTiming_h___ 8 #define mozilla_dom_PerformanceResourceTiming_h___ 9 10 #include "mozilla/UniquePtr.h" 11 #include "nsCOMPtr.h" 12 #include "Performance.h" 13 #include "PerformanceEntry.h" 14 #include "PerformanceServerTiming.h" 15 #include "PerformanceTiming.h" 16 17 namespace mozilla { 18 namespace dom { 19 20 // http://www.w3.org/TR/resource-timing/#performanceresourcetiming 21 class PerformanceResourceTiming : public PerformanceEntry { 22 public: 23 typedef mozilla::TimeStamp TimeStamp; 24 25 NS_DECL_ISUPPORTS_INHERITED 26 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED( 27 PerformanceResourceTiming, PerformanceEntry) 28 29 PerformanceResourceTiming( 30 UniquePtr<PerformanceTimingData>&& aPerformanceTimingData, 31 Performance* aPerformance, const nsAString& aName); 32 33 virtual JSObject* WrapObject(JSContext* aCx, 34 JS::Handle<JSObject*> aGivenProto) override; 35 36 virtual DOMHighResTimeStamp StartTime() const override; 37 Duration()38 virtual DOMHighResTimeStamp Duration() const override { 39 return ResponseEnd() - StartTime(); 40 } 41 GetInitiatorType(nsAString & aInitiatorType)42 void GetInitiatorType(nsAString& aInitiatorType) const { 43 aInitiatorType = mInitiatorType; 44 } 45 SetInitiatorType(const nsAString & aInitiatorType)46 void SetInitiatorType(const nsAString& aInitiatorType) { 47 mInitiatorType = aInitiatorType; 48 } 49 GetNextHopProtocol(nsAString & aNextHopProtocol)50 void GetNextHopProtocol(nsAString& aNextHopProtocol) const { 51 if (mTimingData) { 52 aNextHopProtocol = mTimingData->NextHopProtocol(); 53 } 54 } 55 WorkerStart()56 DOMHighResTimeStamp WorkerStart() const { 57 return mTimingData ? mTimingData->WorkerStartHighRes(mPerformance) : 0; 58 } 59 FetchStart()60 DOMHighResTimeStamp FetchStart() const { 61 return mTimingData ? mTimingData->FetchStartHighRes(mPerformance) : 0; 62 } 63 RedirectStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)64 DOMHighResTimeStamp RedirectStart( 65 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 66 // We have to check if all the redirect URIs had the same origin (since 67 // there is no check in RedirectStartHighRes()) 68 return ReportRedirectForCaller(aSubjectPrincipal) 69 ? mTimingData->RedirectStartHighRes(mPerformance) 70 : 0; 71 } 72 RedirectEnd(Maybe<nsIPrincipal * > & aSubjectPrincipal)73 DOMHighResTimeStamp RedirectEnd( 74 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 75 // We have to check if all the redirect URIs had the same origin (since 76 // there is no check in RedirectEndHighRes()) 77 return ReportRedirectForCaller(aSubjectPrincipal) 78 ? mTimingData->RedirectEndHighRes(mPerformance) 79 : 0; 80 } 81 DomainLookupStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)82 DOMHighResTimeStamp DomainLookupStart( 83 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 84 return TimingAllowedForCaller(aSubjectPrincipal) 85 ? mTimingData->DomainLookupStartHighRes(mPerformance) 86 : 0; 87 } 88 DomainLookupEnd(Maybe<nsIPrincipal * > & aSubjectPrincipal)89 DOMHighResTimeStamp DomainLookupEnd( 90 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 91 return TimingAllowedForCaller(aSubjectPrincipal) 92 ? mTimingData->DomainLookupEndHighRes(mPerformance) 93 : 0; 94 } 95 ConnectStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)96 DOMHighResTimeStamp ConnectStart( 97 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 98 return TimingAllowedForCaller(aSubjectPrincipal) 99 ? mTimingData->ConnectStartHighRes(mPerformance) 100 : 0; 101 } 102 ConnectEnd(Maybe<nsIPrincipal * > & aSubjectPrincipal)103 DOMHighResTimeStamp ConnectEnd( 104 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 105 return TimingAllowedForCaller(aSubjectPrincipal) 106 ? mTimingData->ConnectEndHighRes(mPerformance) 107 : 0; 108 } 109 RequestStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)110 DOMHighResTimeStamp RequestStart( 111 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 112 return TimingAllowedForCaller(aSubjectPrincipal) 113 ? mTimingData->RequestStartHighRes(mPerformance) 114 : 0; 115 } 116 ResponseStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)117 DOMHighResTimeStamp ResponseStart( 118 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 119 return TimingAllowedForCaller(aSubjectPrincipal) 120 ? mTimingData->ResponseStartHighRes(mPerformance) 121 : 0; 122 } 123 ResponseEnd()124 DOMHighResTimeStamp ResponseEnd() const { 125 return mTimingData ? mTimingData->ResponseEndHighRes(mPerformance) : 0; 126 } 127 SecureConnectionStart(Maybe<nsIPrincipal * > & aSubjectPrincipal)128 DOMHighResTimeStamp SecureConnectionStart( 129 Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 130 return TimingAllowedForCaller(aSubjectPrincipal) 131 ? mTimingData->SecureConnectionStartHighRes(mPerformance) 132 : 0; 133 } 134 ToResourceTiming()135 virtual const PerformanceResourceTiming* ToResourceTiming() const override { 136 return this; 137 } 138 TransferSize(Maybe<nsIPrincipal * > & aSubjectPrincipal)139 uint64_t TransferSize(Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 140 return TimingAllowedForCaller(aSubjectPrincipal) 141 ? mTimingData->TransferSize() 142 : 0; 143 } 144 EncodedBodySize(Maybe<nsIPrincipal * > & aSubjectPrincipal)145 uint64_t EncodedBodySize(Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 146 return TimingAllowedForCaller(aSubjectPrincipal) 147 ? mTimingData->EncodedBodySize() 148 : 0; 149 } 150 DecodedBodySize(Maybe<nsIPrincipal * > & aSubjectPrincipal)151 uint64_t DecodedBodySize(Maybe<nsIPrincipal*>& aSubjectPrincipal) const { 152 return TimingAllowedForCaller(aSubjectPrincipal) 153 ? mTimingData->DecodedBodySize() 154 : 0; 155 } 156 157 void GetServerTiming(nsTArray<RefPtr<PerformanceServerTiming>>& aRetval, 158 Maybe<nsIPrincipal*>& aSubjectPrincipal); 159 160 size_t SizeOfIncludingThis( 161 mozilla::MallocSizeOf aMallocSizeOf) const override; 162 163 protected: 164 virtual ~PerformanceResourceTiming(); 165 166 size_t SizeOfExcludingThis( 167 mozilla::MallocSizeOf aMallocSizeOf) const override; 168 169 // Check if caller has access to cross-origin timings, either by the rules 170 // from the spec, or based on addon permissions. 171 bool TimingAllowedForCaller(Maybe<nsIPrincipal*>& aCaller) const; 172 173 // Check if cross-origin redirects should be reported to the caller. 174 bool ReportRedirectForCaller(Maybe<nsIPrincipal*>& aCaller) const; 175 176 nsString mInitiatorType; 177 UniquePtr<PerformanceTimingData> mTimingData; 178 RefPtr<Performance> mPerformance; 179 180 // The same initial requested URI as the `name` attribute. 181 nsCOMPtr<nsIURI> mOriginalURI; 182 }; 183 184 } // namespace dom 185 } // namespace mozilla 186 187 #endif /* mozilla_dom_PerformanceResourceTiming_h___ */ 188