uriloader/preload/PreloadService.h
author Mozilla Releng Treescript <release+treescript@mozilla.org>
Fri, 28 Jan 2022 19:05:43 +0000
changeset 605836 32a2d1ce4bab2979c3be01244f100f000ca77d8e
parent 567477 38345c699f68b7cf69ec49898e5b6c05e283ffec
permissions -rw-r--r--
no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD cy -> 0eecc3c5396a7ce0ae207243a6879f559761b7a3 de -> 9220d3a92bcdc0287d9fedf94dfff7053058ccf1 fr -> 43ef41efa9e6ff87d6b4d0672d44c6d0d02f078c hsb -> 5d446c2cb85ab7fc253ec1b4fb6ed55438b0ef0f hye -> c5edf78a6f636234bb8bba68726a237d4ff9c397 it -> aa7f02187d8cecb017436efd84bf96faf8fbf63c nl -> ce81040d4aa33f478a2b20a5762f720c94b34ae6 sl -> dc3ce6db84b4e461483b2f3f25b0c627b69e446c uk -> 3deee0c202358c3bec34a0d3975ef764abf223a4

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */

#ifndef PreloadService_h__
#define PreloadService_h__

#include "nsIContentPolicy.h"
#include "nsIURI.h"
#include "nsRefPtrHashtable.h"
#include "mozilla/PreloadHashKey.h"

class nsINode;

namespace mozilla {

class PreloaderBase;

namespace dom {

class HTMLLinkElement;
class Document;
enum class ReferrerPolicy : uint8_t;

}  // namespace dom

/**
 * Intended to scope preloads and speculative loads under one roof.  This class
 * is intended to be a member of dom::Document. Provides registration of
 * speculative loads via a `key` which is defined to consist of the URL,
 * resource type, and resource-specific attributes that are further
 * distinguishing loads with otherwise same type and url.
 */
class PreloadService {
 public:
  explicit PreloadService(dom::Document*);
  ~PreloadService();

  // Called by resource loaders to register a running resource load.  This is
  // called for a speculative load when it's started the first time, being it
  // either regular speculative load or a preload.
  //
  // Returns false and does nothing if a preload is already registered under
  // this key, true otherwise.
  bool RegisterPreload(const PreloadHashKey& aKey, PreloaderBase* aPreload);

  // Called when the load is about to be cancelled.  Exact behavior is to be
  // determined yet.
  void DeregisterPreload(const PreloadHashKey& aKey);

  // Called when the scope is to go away.
  void ClearAllPreloads();

  // True when there is a preload registered under the key.
  bool PreloadExists(const PreloadHashKey& aKey);

  // Returns an existing preload under the key or null, when there is none
  // registered under the key.
  already_AddRefed<PreloaderBase> LookupPreload(
      const PreloadHashKey& aKey) const;

  void SetSpeculationBase(nsIURI* aURI) { mSpeculationBaseURI = aURI; }
  already_AddRefed<nsIURI> GetPreloadURI(const nsAString& aURL);

  already_AddRefed<PreloaderBase> PreloadLinkElement(
      dom::HTMLLinkElement* aLink, nsContentPolicyType aPolicyType);

  void PreloadLinkHeader(nsIURI* aURI, const nsAString& aURL,
                         nsContentPolicyType aPolicyType, const nsAString& aAs,
                         const nsAString& aType, const nsAString& aIntegrity,
                         const nsAString& aSrcset, const nsAString& aSizes,
                         const nsAString& aCORS,
                         const nsAString& aReferrerPolicy);

  void PreloadScript(nsIURI* aURI, const nsAString& aType,
                     const nsAString& aCharset, const nsAString& aCrossOrigin,
                     const nsAString& aReferrerPolicy,
                     const nsAString& aIntegrity, bool aScriptFromHead);

  void PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin,
                    const nsAString& aImageReferrerPolicy, bool aIsImgSet);

  void PreloadFont(nsIURI* aURI, const nsAString& aCrossOrigin,
                   const nsAString& aReferrerPolicy);

  void PreloadFetch(nsIURI* aURI, const nsAString& aCrossOrigin,
                    const nsAString& aReferrerPolicy);

  static void NotifyNodeEvent(nsINode* aNode, bool aSuccess);

 private:
  dom::ReferrerPolicy PreloadReferrerPolicy(const nsAString& aReferrerPolicy);
  nsIURI* BaseURIForPreload();

  struct PreloadOrCoalesceResult {
    RefPtr<PreloaderBase> mPreloader;
    bool mAlreadyComplete;
  };

  PreloadOrCoalesceResult PreloadOrCoalesce(
      nsIURI* aURI, const nsAString& aURL, nsContentPolicyType aPolicyType,
      const nsAString& aAs, const nsAString& aType, const nsAString& aCharset,
      const nsAString& aSrcset, const nsAString& aSizes,
      const nsAString& aIntegrity, const nsAString& aCORS,
      const nsAString& aReferrerPolicy, bool aFromHeader);

 private:
  nsRefPtrHashtable<PreloadHashKey, PreloaderBase> mPreloads;

  // Raw pointer only, we are intended to be a direct member of dom::Document
  dom::Document* mDocument;

  // Set by `nsHtml5TreeOpExecutor::SetSpeculationBase`.
  nsCOMPtr<nsIURI> mSpeculationBaseURI;
};

}  // namespace mozilla

#endif