chrome/src/nsChromeProtocolHandler.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial