tor-browser

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

SharedSubResourceCache.cpp (5327B)


      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 "SharedSubResourceCache.h"
      8 
      9 #include "mozilla/RefPtr.h"
     10 #include "mozilla/UniquePtr.h"
     11 #include "mozilla/dom/CacheablePerformanceTimingData.h"
     12 #include "mozilla/dom/Document.h"
     13 #include "mozilla/dom/Performance.h"
     14 #include "mozilla/dom/PerformanceResourceTimingBinding.h"
     15 #include "mozilla/dom/PerformanceStorage.h"
     16 #include "mozilla/dom/PerformanceTiming.h"
     17 #include "mozilla/net/HttpBaseChannel.h"
     18 #include "nsCOMPtr.h"
     19 #include "nsDOMNavigationTiming.h"
     20 #include "nsHttpResponseHead.h"
     21 #include "nsIHttpChannel.h"
     22 #include "nsIRequest.h"
     23 #include "nsITimedChannel.h"
     24 #include "nsPIDOMWindow.h"
     25 #include "nsQueryObject.h"
     26 
     27 namespace mozilla {
     28 
     29 namespace SharedSubResourceCacheUtils {
     30 
     31 void AddPerformanceEntryForCache(
     32    const nsString& aEntryName, const nsString& aInitiatorType,
     33    const SubResourceNetworkMetadataHolder* aNetworkMetadata,
     34    TimeStamp aStartTime, TimeStamp aEndTime, dom::Document* aDocument) {
     35  MOZ_ASSERT(aDocument);
     36 
     37  if (!aNetworkMetadata || !aNetworkMetadata->GetPerfData()) {
     38    return;
     39  }
     40 
     41  nsPIDOMWindowInner* win = aDocument->GetInnerWindow();
     42  if (!win) {
     43    return;
     44  }
     45  RefPtr<dom::Performance> performance = win->GetPerformance();
     46  if (!performance) {
     47    return;
     48  }
     49 
     50  // TODO: Bug 1751383.
     51  auto renderBlocking = dom::RenderBlockingStatusType::Non_blocking;
     52 
     53  UniquePtr<dom::PerformanceTimingData> data(
     54      dom::PerformanceTimingData::Create(*aNetworkMetadata->GetPerfData(), 0,
     55                                         aStartTime, aEndTime, renderBlocking));
     56  if (!data) {
     57    return;
     58  }
     59 
     60  dom::PerformanceStorage* storage = performance->AsPerformanceStorage();
     61  MOZ_ASSERT(storage);
     62  storage->AddEntry(aEntryName, aInitiatorType, std::move(data));
     63 }
     64 
     65 bool ShouldClearEntry(nsIURI* aEntryURI, nsIPrincipal* aEntryLoaderPrincipal,
     66                      nsIPrincipal* aEntryPartitionPrincipal,
     67                      const Maybe<bool>& aChrome,
     68                      const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal,
     69                      const Maybe<nsCString>& aSchemelessSite,
     70                      const Maybe<OriginAttributesPattern>& aPattern,
     71                      const Maybe<nsCString>& aURL) {
     72  if (aChrome.isSome()) {
     73    RefPtr<nsIURI> uri = aEntryURI;
     74    if (!uri) {
     75      // If there's no uri (inline resource) try to use the principal URI.
     76      uri = aEntryLoaderPrincipal->GetURI();
     77    }
     78    const bool isChrome = [&] {
     79      if (uri && (uri->SchemeIs("chrome") || uri->SchemeIs("resource"))) {
     80        return true;
     81      }
     82      if (!aEntryURI && aEntryLoaderPrincipal->IsSystemPrincipal()) {
     83        return true;
     84      }
     85      return false;
     86    }();
     87 
     88    if (*aChrome != isChrome) {
     89      return false;
     90    }
     91 
     92    if (!aPrincipal && !aSchemelessSite && !aURL) {
     93      return true;
     94    }
     95  }
     96 
     97  if (aURL) {
     98    if (!aEntryURI) {
     99      // Inline resources have no URL.
    100      return false;
    101    }
    102    nsAutoCString spec;
    103    nsresult rv = aEntryURI->GetSpec(spec);
    104    if (NS_FAILED(rv)) {
    105      return false;
    106    }
    107    return spec == *aURL;
    108  }
    109 
    110  if (aPrincipal && aEntryPartitionPrincipal->Equals(aPrincipal.ref())) {
    111    return true;
    112  }
    113  if (!aSchemelessSite) {
    114    return false;
    115  }
    116  // Clear by site.
    117  // Clear entries with site. This includes entries which are partitioned
    118  // under other top level sites (= have a partitionKey set).
    119  nsAutoCString principalBaseDomain;
    120  nsresult rv = aEntryPartitionPrincipal->GetBaseDomain(principalBaseDomain);
    121  if (NS_WARN_IF(NS_FAILED(rv))) {
    122    return false;
    123  }
    124  if (principalBaseDomain.Equals(aSchemelessSite.ref()) &&
    125      aPattern.ref().Matches(aEntryPartitionPrincipal->OriginAttributesRef())) {
    126    return true;
    127  }
    128 
    129  // Clear entries partitioned under aSchemelessSite. We need to add the
    130  // partition key filter to aPattern so that we include any OA filtering
    131  // specified by the caller. For example the caller may pass aPattern = {
    132  // privateBrowsingId: 1 } which means we may only clear partitioned
    133  // private browsing data.
    134  OriginAttributesPattern patternWithPartitionKey(aPattern.ref());
    135  patternWithPartitionKey.mPartitionKeyPattern.Construct();
    136  patternWithPartitionKey.mPartitionKeyPattern.Value().mBaseDomain.Construct(
    137      NS_ConvertUTF8toUTF16(aSchemelessSite.ref()));
    138 
    139  return patternWithPartitionKey.Matches(
    140      aEntryPartitionPrincipal->OriginAttributesRef());
    141 }
    142 
    143 }  // namespace SharedSubResourceCacheUtils
    144 
    145 SubResourceNetworkMetadataHolder::~SubResourceNetworkMetadataHolder() = default;
    146 
    147 SubResourceNetworkMetadataHolder::SubResourceNetworkMetadataHolder(
    148    nsIRequest* aRequest) {
    149  nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(aRequest);
    150  if (timedChannel) {
    151    nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
    152    mPerfData.emplace(timedChannel, httpChannel);
    153  }
    154 
    155  RefPtr<net::HttpBaseChannel> httpBaseChannel = do_QueryObject(aRequest);
    156  if (httpBaseChannel) {
    157    mResponseHead = httpBaseChannel->MaybeCloneResponseHeadForCachedResource();
    158  }
    159 }
    160 
    161 }  // namespace mozilla