Coverage Report

Created: 2018-09-25 14:53

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