Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  CookieStoreManager.cpp

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "CookieStoreManager.h"

#include "CookieStoreChild.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerPrivate.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsGlobalWindowInner.h"
#include "nsIGlobalObject.h"
#include "nsIPrincipal.h"

using mozilla::ipc::PrincipalInfo;

namespace mozilla::dom {

NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(CookieStoreManager)

NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CookieStoreManager)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject)
  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
  tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CookieStoreManager)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

CookieStoreManager::CookieStoreManager(
    nsIGlobalObject* aGlobalObject,
    const nsACString& aServiceWorkerRegistrationScopeURL)
    : mGlobalObject(aGlobalObject),
      mScopeURL(aServiceWorkerRegistrationScopeURL) {
  MOZ_ASSERT(aGlobalObject);
}

namespace {

nsIPrincipal* RetrievePrincipal(nsIGlobalObject* aGlobalObject) {
  if (NS_IsMainThread()) {
    nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobalObject);
    if (NS_WARN_IF(!window)) {
      return nullptr;
    }

    return nsGlobalWindowInner::Cast(window)->GetClientPrincipal();
  }

  WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
  MOZ_ASSERT(worker);
  worker->AssertIsOnWorkerThread();

  return worker->GetPrincipal();
}

}  // namespace

CookieStoreManager::~CookieStoreManager() { Shutdown(); }

JSObject* CookieStoreManager::WrapObject(JSContext* aCx,
                                         JS::Handle<JSObject*> aGivenProto) {
  return CookieStoreManager_Binding::Wrap(aCx, this, aGivenProto);
}

already_AddRefed<Promise> CookieStoreManager::Subscribe(
    const CopyableTArray<CookieStoreGetOptions>& aSubscriptions,
    ErrorResult& aRv) {
  return SubscribeOrUnsubscribe(Action::eSubscribe, aSubscriptions, aRv);
}

already_AddRefed<Promise> CookieStoreManager::GetSubscriptions(
    ErrorResult& aRv) {
  nsCOMPtr<nsIPrincipal> principal = RetrievePrincipal(mGlobalObject);
  if (NS_WARN_IF(!principal)) {
    aRv.ThrowInvalidStateError("Invalid context");
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(mGlobalObject, aRv);
  if (NS_WARN_IF(!promise)) {
    return nullptr;
  }

  // ServiceWorkers only have one principal: it's either partitioned or
  // unpartitioned. If the "context" is partitioned, the window or the
  // WorkerPrivate will return a partitioned principal.

  // Let's dispatch a runnable to implement the "Run the following steps in
  // parallel".
  NS_DispatchToCurrentThread(NS_NewRunnableFunction(
      __func__, [self = RefPtr(this), principal = RefPtr(principal.get()),
                 promise = RefPtr(promise)]() {
        if (!self->MaybeCreateActor()) {
          promise->MaybeRejectWithNotAllowedError("Permission denied");
          return;
        }

        PrincipalInfo principalInfo;
        nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
        if (NS_WARN_IF(NS_FAILED(rv))) {
          promise->MaybeResolve(nsTArray<CookieStoreGetOptions>());
          return;
        }

        RefPtr<CookieStoreChild::GetSubscriptionsRequestPromise> ipcPromise =
            self->mActor->SendGetSubscriptionsRequest(principalInfo,
                                                      self->mScopeURL);
        if (NS_WARN_IF(!ipcPromise)) {
          promise->MaybeResolve(nsTArray<CookieStoreGetOptions>());
          return;
        }

        ipcPromise->Then(
            NS_GetCurrentThread(), __func__,
            [promise = RefPtr(promise)](
                const CookieStoreChild::GetSubscriptionsRequestPromise::
                    ResolveOrRejectValue& aResult) {
              if (aResult.IsReject()) {
                promise->MaybeResolve(nsTArray<CookieStoreGetOptions>());
                return;
              }

              nsTArray<CookieStoreGetOptions> results;
              for (const auto& subscription : aResult.ResolveValue()) {
                CookieStoreGetOptions* result = results.AppendElement();

                if (subscription.name().isSome()) {
                  result->mName.Construct();
                  result->mName.Value() = subscription.name().value();
                }

                result->mUrl.Construct();
                result->mUrl.Value() = subscription.url();
              }

              promise->MaybeResolve(results);
            });
      }));

  return promise.forget();
}

already_AddRefed<Promise> CookieStoreManager::Unsubscribe(
    const CopyableTArray<CookieStoreGetOptions>& aSubscriptions,
    ErrorResult& aRv) {
  return SubscribeOrUnsubscribe(Action::eUnsubscribe, aSubscriptions, aRv);
}

already_AddRefed<Promise> CookieStoreManager::SubscribeOrUnsubscribe(
    Action aAction, const CopyableTArray<CookieStoreGetOptions>& aSubscriptions,
    ErrorResult& aRv) {
  nsCOMPtr<nsIPrincipal> principal = RetrievePrincipal(mGlobalObject);
  if (NS_WARN_IF(!principal)) {
    aRv.ThrowInvalidStateError("Invalid context");
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(mGlobalObject, aRv);
  if (NS_WARN_IF(!promise)) {
    return nullptr;
  }

  // ServiceWorkers only have one principal: it's either partitioned or
  // unpartitioned. If the "context" is partitioned, the window or the
  // WorkerPrivate will return a partitioned principal.

  NS_DispatchToCurrentThread(NS_NewRunnableFunction(
      __func__,
      [self = RefPtr(this), promise = RefPtr(promise),
       principal = RefPtr(principal.get()), aSubscriptions, aAction]() {
        nsCOMPtr<nsIURI> baseURI;
        nsresult rv = NS_NewURI(getter_AddRefs(baseURI), self->mScopeURL,
                                nullptr, nullptr);
        if (NS_WARN_IF(NS_FAILED(rv))) {
          promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(self->mScopeURL);
          return;
        }

        if (NS_WARN_IF(!baseURI)) {
          promise->MaybeRejectWithSecurityError(
              "Couldn't acquire the base URI of this context");
          return;
        }

        nsTArray<CookieSubscription> subscriptions;

        for (const CookieStoreGetOptions& subscription : aSubscriptions) {
          nsString subscriptionURL;
          if (subscription.mUrl.WasPassed()) {
            subscriptionURL.Assign(subscription.mUrl.Value());
          }

          nsCOMPtr<nsIURI> uri;
          rv =
              NS_NewURI(getter_AddRefs(uri), subscriptionURL, nullptr, baseURI);
          if (NS_WARN_IF(NS_FAILED(rv))) {
            promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
                NS_ConvertUTF16toUTF8(subscriptionURL));
            return;
          }

          nsAutoCString subscriptionURI;
          rv = uri->GetSpec(subscriptionURI);
          if (NS_WARN_IF(NS_FAILED(rv))) {
            promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
                NS_ConvertUTF16toUTF8(subscriptionURL));
            return;
          }

          if (!StringBeginsWith(subscriptionURI, self->mScopeURL)) {
            promise->MaybeRejectWithTypeError<MSG_INVALID_URL>(
                NS_ConvertUTF16toUTF8(subscriptionURL));
            return;
          }

          subscriptions.AppendElement(CookieSubscription{
              subscription.mName.WasPassed() ? Some(subscription.mName.Value())
                                             : Nothing(),
              NS_ConvertUTF8toUTF16(subscriptionURI)});
        }

        if (!self->MaybeCreateActor()) {
          promise->MaybeRejectWithNotAllowedError("Permission denied");
          return;
        }

        PrincipalInfo principalInfo;
        rv = PrincipalToPrincipalInfo(principal, &principalInfo);
        if (NS_WARN_IF(NS_FAILED(rv))) {
          promise->MaybeResolveWithUndefined();
          return;
        }

        RefPtr<CookieStoreChild::SubscribeOrUnsubscribeRequestPromise>
            ipcPromise = self->mActor->SendSubscribeOrUnsubscribeRequest(
                principalInfo, self->mScopeURL, subscriptions,
                (aAction == Action::eSubscribe));
        if (NS_WARN_IF(!ipcPromise)) {
          promise->MaybeResolveWithUndefined();
          return;
        }

        ipcPromise->Then(
            NS_GetCurrentThread(), __func__,
            [promise = RefPtr(promise)](
                const CookieStoreChild::SubscribeOrUnsubscribeRequestPromise::
                    ResolveOrRejectValue& aResult) {
              // TODO We don't really want to expose internal errors.
              promise->MaybeResolveWithUndefined();
            });
      }));

  return promise.forget();
}

bool CookieStoreManager::MaybeCreateActor() {
  if (mActor) {
    return mActor->CanSend();
  }

  mozilla::ipc::PBackgroundChild* actorChild =
      mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
  if (NS_WARN_IF(!actorChild)) {
    // The process is probably shutting down. Let's return a 'generic' error.
    return false;
  }

  PCookieStoreChild* actor = actorChild->SendPCookieStoreConstructor();
  if (!actor) {
    return false;
  }

  mActor = static_cast<CookieStoreChild*>(actor);

  return true;
}

void CookieStoreManager::Shutdown() {
  if (mActor) {
    mActor->Close();
    mActor = nullptr;
  }
}

}  // namespace mozilla::dom

Messung V0.5 in Prozent
C=86 H=91 G=88

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002