tor-browser

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

SubstitutingProtocolHandler.h (4659B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef SubstitutingProtocolHandler_h___
      8 #define SubstitutingProtocolHandler_h___
      9 
     10 #include "nsISubstitutingProtocolHandler.h"
     11 
     12 #include "nsTHashMap.h"
     13 #include "nsStandardURL.h"
     14 #include "nsJARURI.h"
     15 #include "mozilla/chrome/RegistryMessageUtils.h"
     16 #include "mozilla/RWLock.h"
     17 
     18 class nsIIOService;
     19 
     20 namespace mozilla {
     21 namespace net {
     22 
     23 //
     24 // Base class for resource://-like substitution protocols.
     25 //
     26 // If you add a new protocol, make sure to change nsChromeRegistryChrome
     27 // to properly invoke CollectSubstitutions at the right time.
     28 class SubstitutingProtocolHandler {
     29 public:
     30  explicit SubstitutingProtocolHandler(const char* aScheme,
     31                                       bool aEnforceFileOrJar = true);
     32 
     33  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SubstitutingProtocolHandler);
     34  NS_DECL_NON_VIRTUAL_NSIPROTOCOLHANDLER;
     35  NS_DECL_NON_VIRTUAL_NSISUBSTITUTINGPROTOCOLHANDLER;
     36 
     37  bool HasSubstitution(const nsACString& aRoot) const {
     38    AutoReadLock lock(const_cast<RWLock&>(mSubstitutionsLock));
     39    return mSubstitutions.Get(aRoot, nullptr);
     40  }
     41 
     42  nsresult NewURI(const nsACString& aSpec, const char* aCharset,
     43                  nsIURI* aBaseURI, nsIURI** aResult);
     44 
     45  [[nodiscard]] nsresult CollectSubstitutions(
     46      nsTArray<SubstitutionMapping>& aMappings);
     47 
     48 protected:
     49  virtual ~SubstitutingProtocolHandler() = default;
     50  void ConstructInternal();
     51 
     52  [[nodiscard]] nsresult SendSubstitution(const nsACString& aRoot,
     53                                          nsIURI* aBaseURI, uint32_t aFlags);
     54 
     55  nsresult GetSubstitutionFlags(const nsACString& root, uint32_t* flags);
     56 
     57  // Override this in the subclass to try additional lookups after checking
     58  // mSubstitutions.
     59  [[nodiscard]] virtual nsresult GetSubstitutionInternal(
     60      const nsACString& aRoot, nsIURI** aResult) {
     61    *aResult = nullptr;
     62    return NS_ERROR_NOT_AVAILABLE;
     63  }
     64 
     65  // Override this in the subclass to check for special case when resolving URIs
     66  // _before_ checking substitutions.
     67  [[nodiscard]] virtual bool ResolveSpecialCases(const nsACString& aHost,
     68                                                 const nsACString& aPath,
     69                                                 const nsACString& aPathname,
     70                                                 nsACString& aResult) {
     71    return false;
     72  }
     73 
     74  // This method should only return RESOLVE_JAR_URI when
     75  // GetSubstitutionalInternal will return nsIJARURI instead of a nsIFileURL.
     76  // Currently, this only happens on Android.
     77  [[nodiscard]] virtual uint32_t GetJARFlags(const nsACString& aRoot) {
     78    return 0;
     79  }
     80 
     81  // Override this in the subclass to check for special case when opening
     82  // channels.
     83  [[nodiscard]] virtual nsresult SubstituteChannel(nsIURI* uri,
     84                                                   nsILoadInfo* aLoadInfo,
     85                                                   nsIChannel** result) {
     86    return NS_OK;
     87  }
     88 
     89  nsIIOService* IOService() { return mIOService; }
     90 
     91 private:
     92  struct SubstitutionEntry {
     93    nsCOMPtr<nsIURI> baseURI;
     94    uint32_t flags = 0;
     95  };
     96 
     97  // Notifies all observers that a new substitution from |aRoot| to
     98  // |aBaseURI| has been set/installed for this protocol handler.
     99  void NotifyObservers(const nsACString& aRoot, nsIURI* aBaseURI);
    100 
    101  nsCString mScheme;
    102 
    103  RWLock mSubstitutionsLock;
    104  nsTHashMap<nsCStringHashKey, SubstitutionEntry> mSubstitutions
    105      MOZ_GUARDED_BY(mSubstitutionsLock);
    106  nsCOMPtr<nsIIOService> mIOService;
    107 
    108  // Returns a SubstitutingJARURI if |aUrl| maps to a |jar:| URI,
    109  // otherwise will return |aURL|
    110  nsresult ResolveJARURI(nsIURL* aURL, nsIURI** aResult);
    111 
    112  // In general, we expect the principal of a document loaded from a
    113  // substituting URI to be a content principal for that URI (rather than
    114  // a principal for whatever is underneath). However, this only works if
    115  // the protocol handler for the underlying URI doesn't set an explicit
    116  // owner (which chrome:// does, for example). So we want to require that
    117  // substituting URIs only map to other URIs of the same type, or to
    118  // file:// and jar:// URIs.
    119  //
    120  // Enforcing this for ye olde resource:// URIs could carry compat risks, so
    121  // we just try to enforce it on new protocols going forward.
    122  bool mEnforceFileOrJar;
    123 };
    124 
    125 }  // namespace net
    126 }  // namespace mozilla
    127 
    128 #endif /* SubstitutingProtocolHandler_h___ */