/src/mozilla-central/dom/performance/PerformanceResourceTiming.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "PerformanceResourceTiming.h" |
8 | | #include "mozilla/dom/PerformanceResourceTimingBinding.h" |
9 | | #include "nsNetUtil.h" |
10 | | #include "nsArrayUtils.h" |
11 | | |
12 | | using namespace mozilla::dom; |
13 | | |
14 | | NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceResourceTiming, |
15 | | PerformanceEntry, |
16 | | mPerformance) |
17 | | |
18 | 0 | NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceResourceTiming, |
19 | 0 | PerformanceEntry) |
20 | 0 | NS_IMPL_CYCLE_COLLECTION_TRACE_END |
21 | | |
22 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceResourceTiming) |
23 | 0 | NS_INTERFACE_MAP_END_INHERITING(PerformanceEntry) |
24 | | |
25 | | NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry) |
26 | | NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry) |
27 | | |
28 | | PerformanceResourceTiming::PerformanceResourceTiming(UniquePtr<PerformanceTimingData>&& aPerformanceTiming, |
29 | | Performance* aPerformance, |
30 | | const nsAString& aName) |
31 | | : PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource")) |
32 | | , mTimingData(std::move(aPerformanceTiming)) |
33 | | , mPerformance(aPerformance) |
34 | 0 | { |
35 | 0 | MOZ_ASSERT(aPerformance, "Parent performance object should be provided"); |
36 | 0 | if (NS_IsMainThread()) { |
37 | 0 | // Used to check if an addon content script has access to this timing. |
38 | 0 | // We don't need it in workers, and ignore mOriginalURI if null. |
39 | 0 | NS_NewURI(getter_AddRefs(mOriginalURI), aName); |
40 | 0 | } |
41 | 0 | } |
42 | | |
43 | | PerformanceResourceTiming::~PerformanceResourceTiming() |
44 | 0 | { |
45 | 0 | } |
46 | | |
47 | | DOMHighResTimeStamp |
48 | | PerformanceResourceTiming::StartTime() const |
49 | 0 | { |
50 | 0 | // Force the start time to be the earliest of: |
51 | 0 | // - RedirectStart |
52 | 0 | // - WorkerStart |
53 | 0 | // - AsyncOpen |
54 | 0 | // Ignore zero values. The RedirectStart and WorkerStart values |
55 | 0 | // can come from earlier redirected channels prior to the AsyncOpen |
56 | 0 | // time being recorded. |
57 | 0 | DOMHighResTimeStamp redirect = |
58 | 0 | mTimingData->RedirectStartHighRes(mPerformance); |
59 | 0 | redirect = redirect ? redirect : DBL_MAX; |
60 | 0 |
|
61 | 0 | DOMHighResTimeStamp worker = mTimingData->WorkerStartHighRes(mPerformance); |
62 | 0 | worker = worker ? worker : DBL_MAX; |
63 | 0 |
|
64 | 0 | DOMHighResTimeStamp asyncOpen = mTimingData->AsyncOpenHighRes(mPerformance); |
65 | 0 |
|
66 | 0 | return std::min(asyncOpen, std::min(redirect, worker)); |
67 | 0 | } |
68 | | |
69 | | JSObject* |
70 | | PerformanceResourceTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
71 | 0 | { |
72 | 0 | return PerformanceResourceTiming_Binding::Wrap(aCx, this, aGivenProto); |
73 | 0 | } |
74 | | |
75 | | size_t |
76 | | PerformanceResourceTiming::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
77 | 0 | { |
78 | 0 | return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); |
79 | 0 | } |
80 | | |
81 | | size_t |
82 | | PerformanceResourceTiming::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
83 | 0 | { |
84 | 0 | return PerformanceEntry::SizeOfExcludingThis(aMallocSizeOf) + |
85 | 0 | mInitiatorType.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + |
86 | 0 | (mTimingData |
87 | 0 | ? mTimingData->NextHopProtocol().SizeOfExcludingThisIfUnshared(aMallocSizeOf) |
88 | 0 | : 0); |
89 | 0 | } |
90 | | |
91 | | void |
92 | | PerformanceResourceTiming::GetServerTiming( |
93 | | nsTArray<RefPtr<PerformanceServerTiming>>& aRetval, |
94 | | Maybe<nsIPrincipal*>& aSubjectPrincipal) |
95 | 0 | { |
96 | 0 | aRetval.Clear(); |
97 | 0 | if (!TimingAllowedForCaller(aSubjectPrincipal)) { |
98 | 0 | return; |
99 | 0 | } |
100 | 0 | |
101 | 0 | nsTArray<nsCOMPtr<nsIServerTiming>> serverTimingArray = mTimingData->GetServerTiming(); |
102 | 0 | uint32_t length = serverTimingArray.Length(); |
103 | 0 | for (uint32_t index = 0; index < length; ++index) { |
104 | 0 | nsCOMPtr<nsIServerTiming> serverTiming = serverTimingArray.ElementAt(index); |
105 | 0 | MOZ_ASSERT(serverTiming); |
106 | 0 |
|
107 | 0 | aRetval.AppendElement( |
108 | 0 | new PerformanceServerTiming(GetParentObject(), serverTiming)); |
109 | 0 | } |
110 | 0 | } |
111 | | |
112 | | bool |
113 | | PerformanceResourceTiming::TimingAllowedForCaller(Maybe<nsIPrincipal*>& aCaller) const |
114 | 0 | { |
115 | 0 | if (!mTimingData) { |
116 | 0 | return false; |
117 | 0 | } |
118 | 0 | |
119 | 0 | if (mTimingData->TimingAllowed()) { |
120 | 0 | return true; |
121 | 0 | } |
122 | 0 | |
123 | 0 | // Check if the addon has permission to access the cross-origin resource. |
124 | 0 | return mOriginalURI && aCaller.isSome() && |
125 | 0 | BasePrincipal::Cast(aCaller.value())->AddonAllowsLoad(mOriginalURI); |
126 | 0 | } |
127 | | |
128 | | bool |
129 | | PerformanceResourceTiming::ReportRedirectForCaller(Maybe<nsIPrincipal*>& aCaller) const |
130 | 0 | { |
131 | 0 | if (!mTimingData) { |
132 | 0 | return false; |
133 | 0 | } |
134 | 0 | |
135 | 0 | if (mTimingData->ShouldReportCrossOriginRedirect()) { |
136 | 0 | return true; |
137 | 0 | } |
138 | 0 | |
139 | 0 | // Only report cross-origin redirect if the addon has <all_urls> permission. |
140 | 0 | return aCaller.isSome() && |
141 | 0 | BasePrincipal::Cast(aCaller.value())->AddonHasPermission(nsGkAtoms::all_urlsPermission); |
142 | 0 | } |