tor-browser

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

NavigationPreloadManager.cpp (4370B)


      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 "NavigationPreloadManager.h"
      8 
      9 #include "ServiceWorkerUtils.h"
     10 #include "mozilla/StaticPrefs_dom.h"
     11 #include "mozilla/dom/NavigationPreloadManagerBinding.h"
     12 #include "mozilla/dom/Promise.h"
     13 #include "mozilla/dom/ServiceWorker.h"
     14 #include "mozilla/ipc/MessageChannel.h"
     15 #include "nsNetUtil.h"
     16 
     17 namespace mozilla::dom {
     18 
     19 NS_IMPL_CYCLE_COLLECTING_ADDREF(NavigationPreloadManager)
     20 NS_IMPL_CYCLE_COLLECTING_RELEASE(NavigationPreloadManager)
     21 
     22 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NavigationPreloadManager)
     23  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     24  NS_INTERFACE_MAP_ENTRY(nsISupports)
     25 NS_INTERFACE_MAP_END
     26 
     27 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(NavigationPreloadManager,
     28                                      mServiceWorkerRegistration)
     29 
     30 /* static */
     31 bool NavigationPreloadManager::IsValidHeader(const nsACString& aHeader) {
     32  return NS_IsReasonableHTTPHeaderValue(aHeader);
     33 }
     34 
     35 bool NavigationPreloadManager::IsEnabled(JSContext* aCx, JSObject* aGlobal) {
     36  return StaticPrefs::dom_serviceWorkers_navigationPreload_enabled() &&
     37         ServiceWorkersEnabled(aCx, aGlobal);
     38 }
     39 
     40 NavigationPreloadManager::NavigationPreloadManager(
     41    RefPtr<ServiceWorkerRegistration>& aServiceWorkerRegistration)
     42    : mServiceWorkerRegistration(aServiceWorkerRegistration) {}
     43 
     44 JSObject* NavigationPreloadManager::WrapObject(
     45    JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
     46  return NavigationPreloadManager_Binding::Wrap(aCx, this, aGivenProto);
     47 }
     48 
     49 already_AddRefed<Promise> NavigationPreloadManager::SetEnabled(
     50    bool aEnabled, ErrorResult& aError) {
     51  RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError);
     52 
     53  if (NS_WARN_IF(aError.Failed())) {
     54    return nullptr;
     55  }
     56 
     57  if (!mServiceWorkerRegistration) {
     58    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     59    return promise.forget();
     60  }
     61 
     62  mServiceWorkerRegistration->SetNavigationPreloadEnabled(
     63      aEnabled,
     64      [promise](bool aSuccess) {
     65        if (aSuccess) {
     66          promise->MaybeResolveWithUndefined();
     67          return;
     68        }
     69        promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     70      },
     71      [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); });
     72 
     73  return promise.forget();
     74 }
     75 
     76 already_AddRefed<Promise> NavigationPreloadManager::Enable(
     77    ErrorResult& aError) {
     78  return SetEnabled(true, aError);
     79 }
     80 
     81 already_AddRefed<Promise> NavigationPreloadManager::Disable(
     82    ErrorResult& aError) {
     83  return SetEnabled(false, aError);
     84 }
     85 
     86 already_AddRefed<Promise> NavigationPreloadManager::SetHeaderValue(
     87    const nsACString& aHeader, ErrorResult& aError) {
     88  RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError);
     89 
     90  if (NS_WARN_IF(aError.Failed())) {
     91    return nullptr;
     92  }
     93 
     94  if (!IsValidHeader(aHeader)) {
     95    promise->MaybeRejectWithTypeError<MSG_INVALID_HEADER_VALUE>(aHeader);
     96    return promise.forget();
     97  }
     98 
     99  if (!mServiceWorkerRegistration) {
    100    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    101    return promise.forget();
    102  }
    103 
    104  mServiceWorkerRegistration->SetNavigationPreloadHeader(
    105      nsAutoCString(aHeader),
    106      [promise](bool aSuccess) {
    107        if (aSuccess) {
    108          promise->MaybeResolveWithUndefined();
    109          return;
    110        }
    111        promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    112      },
    113      [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); });
    114 
    115  return promise.forget();
    116 }
    117 
    118 already_AddRefed<Promise> NavigationPreloadManager::GetState(
    119    ErrorResult& aError) {
    120  RefPtr<Promise> promise = Promise::Create(GetParentObject(), aError);
    121 
    122  if (NS_WARN_IF(aError.Failed())) {
    123    return nullptr;
    124  }
    125 
    126  if (!mServiceWorkerRegistration) {
    127    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    128    return promise.forget();
    129  }
    130 
    131  mServiceWorkerRegistration->GetNavigationPreloadState(
    132      [promise](NavigationPreloadState&& aState) {
    133        promise->MaybeResolve(std::move(aState));
    134      },
    135      [promise](ErrorResult&& aRv) { promise->MaybeReject(std::move(aRv)); });
    136 
    137  return promise.forget();
    138 }
    139 
    140 }  // namespace mozilla::dom