tor-browser

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

nsChromeProtocolHandler.cpp (5178B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=4 sw=2 sts=2 et cin: */
      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 /*
      8 
      9  A protocol handler for ``chrome:''
     10 
     11 */
     12 
     13 #include "nsChromeProtocolHandler.h"
     14 #include "nsChromeRegistry.h"
     15 #include "nsCOMPtr.h"
     16 #include "nsContentUtils.h"
     17 #include "nsThreadUtils.h"
     18 #include "nsIChannel.h"
     19 #include "nsIChromeRegistry.h"
     20 #include "nsIFile.h"
     21 #include "nsIFileChannel.h"
     22 #include "nsIStandardURL.h"
     23 #include "nsNetUtil.h"
     24 #include "nsNetCID.h"
     25 #include "nsIURL.h"
     26 #include "nsString.h"
     27 #include "nsStandardURL.h"
     28 
     29 ////////////////////////////////////////////////////////////////////////////////
     30 
     31 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler, nsIProtocolHandler,
     32                  nsISupportsWeakReference)
     33 
     34 ////////////////////////////////////////////////////////////////////////////////
     35 // nsIProtocolHandler methods:
     36 
     37 NS_IMETHODIMP
     38 nsChromeProtocolHandler::GetScheme(nsACString& result) {
     39  result.AssignLiteral("chrome");
     40  return NS_OK;
     41 }
     42 
     43 NS_IMETHODIMP
     44 nsChromeProtocolHandler::AllowPort(int32_t port, const char* scheme,
     45                                   bool* _retval) {
     46  // don't override anything.
     47  *_retval = false;
     48  return NS_OK;
     49 }
     50 
     51 /* static */ nsresult nsChromeProtocolHandler::CreateNewURI(
     52    const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI,
     53    nsIURI** result) {
     54  // Chrome: URLs (currently) have no additional structure beyond that provided
     55  // by standard URLs, so there is no "outer" given to CreateInstance
     56  nsresult rv;
     57  nsCOMPtr<nsIURI> surl;
     58  rv =
     59      NS_MutateURI(new mozilla::net::nsStandardURL::Mutator())
     60          .Apply(&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_STANDARD,
     61                 -1, aSpec, aCharset, aBaseURI, nullptr)
     62 
     63          .Finalize(surl);
     64  if (NS_FAILED(rv)) {
     65    return rv;
     66  }
     67 
     68  // Canonify the "chrome:" URL; e.g., so that we collapse
     69  // "chrome://navigator/content/" and "chrome://navigator/content"
     70  // and "chrome://navigator/content/navigator.xul".
     71 
     72  rv = nsChromeRegistry::Canonify(surl);
     73  (void)NS_WARN_IF(NS_FAILED(rv));
     74 
     75  surl.forget(result);
     76  return NS_OK;
     77 }
     78 
     79 NS_IMETHODIMP
     80 nsChromeProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
     81                                    nsIChannel** aResult) {
     82  nsresult rv;
     83 
     84  NS_ENSURE_ARG_POINTER(aURI);
     85  NS_ENSURE_ARG_POINTER(aLoadInfo);
     86 
     87  MOZ_ASSERT(aResult, "Null out param");
     88 
     89  nsCOMPtr<nsIURI> debugURL = aURI;
     90  rv = nsChromeRegistry::Canonify(debugURL);
     91  NS_ENSURE_SUCCESS(rv, rv);
     92 
     93  nsCOMPtr<nsIChannel> result;
     94 
     95  if (!nsChromeRegistry::gChromeRegistry) {
     96    // We don't actually want this ref, we just want the service to
     97    // initialize if it hasn't already.
     98    nsCOMPtr<nsIChromeRegistry> reg = mozilla::services::GetChromeRegistry();
     99    NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
    100  }
    101 
    102  nsCOMPtr<nsIURI> resolvedURI;
    103  rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(
    104      aURI, getter_AddRefs(resolvedURI));
    105  if (NS_FAILED(rv)) {
    106 #ifdef DEBUG
    107    printf("Couldn't convert chrome URL: %s\n", aURI->GetSpecOrDefault().get());
    108 #endif
    109    return rv;
    110  }
    111 
    112  // We don't want to allow the inner protocol handler modify the result
    113  // principal URI since we want either |aURI| or anything pre-set by upper
    114  // layers to prevail.
    115  nsCOMPtr<nsIURI> savedResultPrincipalURI;
    116  rv =
    117      aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
    118  NS_ENSURE_SUCCESS(rv, rv);
    119 
    120  rv = NS_NewChannelInternal(getter_AddRefs(result), resolvedURI, aLoadInfo);
    121  NS_ENSURE_SUCCESS(rv, rv);
    122 
    123 #ifdef DEBUG
    124  nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
    125  if (fileChan) {
    126    nsCOMPtr<nsIFile> file;
    127    fileChan->GetFile(getter_AddRefs(file));
    128 
    129    bool exists = false;
    130    file->Exists(&exists);
    131    if (!exists) {
    132      printf("Chrome file doesn't exist: %s\n",
    133             file->HumanReadablePath().get());
    134    }
    135  }
    136 #endif
    137 
    138  // Make sure that the channel remembers where it was
    139  // originally loaded from.
    140  rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
    141  NS_ENSURE_SUCCESS(rv, rv);
    142  rv = result->SetOriginalURI(aURI);
    143  if (NS_FAILED(rv)) return rv;
    144 
    145  // Use a system principal for /content and /skin files.
    146  // See bug 1855225 for discussion about whether to extend it more generally
    147  // to other chrome:// URIs.
    148  nsAutoCString path;
    149  aURI->GetPathQueryRef(path);
    150  if (StringBeginsWith(path, "/content/"_ns) ||
    151      StringBeginsWith(path, "/skin/"_ns)) {
    152    result->SetOwner(nsContentUtils::GetSystemPrincipal());
    153  }
    154 
    155  // XXX Removed dependency-tracking code from here, because we're not
    156  // tracking them anyways (with fastload we checked only in DEBUG
    157  // and with startupcache not at all), but this is where we would start
    158  // if we need to re-add.
    159  // See bug 531886, bug 533038.
    160  result->SetContentCharset("UTF-8"_ns);
    161 
    162  result.forget(aResult);
    163  return NS_OK;
    164 }
    165 
    166 ////////////////////////////////////////////////////////////////////////////////