chrome/src/nsChromeProtocolHandler.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim:set ts=4 sw=4 sts=4 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/. */
     7 /*
     9   A protocol handler for ``chrome:''
    11 */
    13 #include "nsChromeProtocolHandler.h"
    14 #include "nsChromeRegistry.h"
    15 #include "nsCOMPtr.h"
    16 #include "nsThreadUtils.h"
    17 #include "nsIChannel.h"
    18 #include "nsIChromeRegistry.h"
    19 #include "nsIFile.h"
    20 #include "nsIFileChannel.h"
    21 #include "nsIIOService.h"
    22 #include "nsILoadGroup.h"
    23 #include "nsIScriptSecurityManager.h"
    24 #include "nsIStandardURL.h"
    25 #include "nsNetUtil.h"
    26 #include "nsString.h"
    28 ////////////////////////////////////////////////////////////////////////////////
    30 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler,
    31                   nsIProtocolHandler,
    32                   nsISupportsWeakReference)
    34 ////////////////////////////////////////////////////////////////////////////////
    35 // nsIProtocolHandler methods:
    37 NS_IMETHODIMP
    38 nsChromeProtocolHandler::GetScheme(nsACString &result)
    39 {
    40     result.AssignLiteral("chrome");
    41     return NS_OK;
    42 }
    44 NS_IMETHODIMP
    45 nsChromeProtocolHandler::GetDefaultPort(int32_t *result)
    46 {
    47     *result = -1;        // no port for chrome: URLs
    48     return NS_OK;
    49 }
    51 NS_IMETHODIMP
    52 nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
    53 {
    54     // don't override anything.
    55     *_retval = false;
    56     return NS_OK;
    57 }
    59 NS_IMETHODIMP
    60 nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result)
    61 {
    62     *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
    63     return NS_OK;
    64 }
    66 NS_IMETHODIMP
    67 nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
    68                                 const char *aCharset,
    69                                 nsIURI *aBaseURI,
    70                                 nsIURI **result)
    71 {
    72     nsresult rv;
    74     // Chrome: URLs (currently) have no additional structure beyond that provided
    75     // by standard URLs, so there is no "outer" given to CreateInstance
    77     nsCOMPtr<nsIStandardURL> surl(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv));
    78     NS_ENSURE_SUCCESS(rv, rv);
    80     rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI);
    81     if (NS_FAILED(rv))
    82         return rv;
    84     nsCOMPtr<nsIURL> url(do_QueryInterface(surl, &rv));
    85     NS_ENSURE_SUCCESS(rv, rv);
    87     // Canonify the "chrome:" URL; e.g., so that we collapse
    88     // "chrome://navigator/content/" and "chrome://navigator/content"
    89     // and "chrome://navigator/content/navigator.xul".
    91     rv = nsChromeRegistry::Canonify(url);
    92     if (NS_FAILED(rv))
    93         return rv;
    95     surl->SetMutable(false);
    97     NS_ADDREF(*result = url);
    98     return NS_OK;
    99 }
   101 NS_IMETHODIMP
   102 nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
   103                                     nsIChannel* *aResult)
   104 {
   105     nsresult rv;
   107     NS_ENSURE_ARG_POINTER(aURI);
   108     NS_PRECONDITION(aResult, "Null out param");
   110 #ifdef DEBUG
   111     // Check that the uri we got is already canonified
   112     nsresult debug_rv;
   113     nsCOMPtr<nsIURI> debugClone;
   114     debug_rv = aURI->Clone(getter_AddRefs(debugClone));
   115     if (NS_SUCCEEDED(debug_rv)) {
   116         nsCOMPtr<nsIURL> debugURL (do_QueryInterface(debugClone));
   117         debug_rv = nsChromeRegistry::Canonify(debugURL);
   118         if (NS_SUCCEEDED(debug_rv)) {
   119             bool same;
   120             debug_rv = aURI->Equals(debugURL, &same);
   121             if (NS_SUCCEEDED(debug_rv)) {
   122                 NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
   123             }
   124         }
   125     }
   126 #endif
   128     nsCOMPtr<nsIChannel> result;
   130     if (!nsChromeRegistry::gChromeRegistry) {
   131         // We don't actually want this ref, we just want the service to
   132         // initialize if it hasn't already.
   133         nsCOMPtr<nsIChromeRegistry> reg =
   134             mozilla::services::GetChromeRegistryService();
   135         NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
   136     }
   138     nsCOMPtr<nsIURI> resolvedURI;
   139     rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
   140     if (NS_FAILED(rv)) {
   141 #ifdef DEBUG
   142         nsAutoCString spec;
   143         aURI->GetSpec(spec);
   144         printf("Couldn't convert chrome URL: %s\n", spec.get());
   145 #endif
   146         return rv;
   147     }
   149     nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
   150     NS_ENSURE_SUCCESS(rv, rv);
   152     rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result));
   153     if (NS_FAILED(rv)) return rv;
   155 #ifdef DEBUG
   156     nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
   157     if (fileChan) {
   158         nsCOMPtr<nsIFile> file;
   159         fileChan->GetFile(getter_AddRefs(file));
   161         bool exists = false;
   162         file->Exists(&exists);
   163         if (!exists) {
   164             nsAutoCString path;
   165             file->GetNativePath(path);
   166             printf("Chrome file doesn't exist: %s\n", path.get());
   167         }
   168     }
   169 #endif
   171     // Make sure that the channel remembers where it was
   172     // originally loaded from.
   173     nsLoadFlags loadFlags = 0;
   174     result->GetLoadFlags(&loadFlags);
   175     result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
   176     rv = result->SetOriginalURI(aURI);
   177     if (NS_FAILED(rv)) return rv;
   179     // Get a system principal for content files and set the owner
   180     // property of the result
   181     nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
   182     nsAutoCString path;
   183     rv = url->GetPath(path);
   184     if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/")))
   185     {
   186         nsCOMPtr<nsIScriptSecurityManager> securityManager =
   187                  do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
   188         if (NS_FAILED(rv)) return rv;
   190         nsCOMPtr<nsIPrincipal> principal;
   191         rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
   192         if (NS_FAILED(rv)) return rv;
   194         nsCOMPtr<nsISupports> owner = do_QueryInterface(principal);
   195         result->SetOwner(owner);
   196     }
   198     // XXX Removed dependency-tracking code from here, because we're not
   199     // tracking them anyways (with fastload we checked only in DEBUG
   200     // and with startupcache not at all), but this is where we would start
   201     // if we need to re-add.
   202     // See bug 531886, bug 533038.
   203     result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
   205     *aResult = result;
   206     NS_ADDREF(*aResult);
   207     return NS_OK;
   208 }
   210 ////////////////////////////////////////////////////////////////////////////////

mercurial