tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PerformanceResourceTiming.cpp (5667B)


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