1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/chrome/src/nsChromeProtocolHandler.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,210 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim:set ts=4 sw=4 sts=4 et cin: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* 1.11 + 1.12 + A protocol handler for ``chrome:'' 1.13 + 1.14 +*/ 1.15 + 1.16 +#include "nsChromeProtocolHandler.h" 1.17 +#include "nsChromeRegistry.h" 1.18 +#include "nsCOMPtr.h" 1.19 +#include "nsThreadUtils.h" 1.20 +#include "nsIChannel.h" 1.21 +#include "nsIChromeRegistry.h" 1.22 +#include "nsIFile.h" 1.23 +#include "nsIFileChannel.h" 1.24 +#include "nsIIOService.h" 1.25 +#include "nsILoadGroup.h" 1.26 +#include "nsIScriptSecurityManager.h" 1.27 +#include "nsIStandardURL.h" 1.28 +#include "nsNetUtil.h" 1.29 +#include "nsString.h" 1.30 + 1.31 +//////////////////////////////////////////////////////////////////////////////// 1.32 + 1.33 +NS_IMPL_ISUPPORTS(nsChromeProtocolHandler, 1.34 + nsIProtocolHandler, 1.35 + nsISupportsWeakReference) 1.36 + 1.37 +//////////////////////////////////////////////////////////////////////////////// 1.38 +// nsIProtocolHandler methods: 1.39 + 1.40 +NS_IMETHODIMP 1.41 +nsChromeProtocolHandler::GetScheme(nsACString &result) 1.42 +{ 1.43 + result.AssignLiteral("chrome"); 1.44 + return NS_OK; 1.45 +} 1.46 + 1.47 +NS_IMETHODIMP 1.48 +nsChromeProtocolHandler::GetDefaultPort(int32_t *result) 1.49 +{ 1.50 + *result = -1; // no port for chrome: URLs 1.51 + return NS_OK; 1.52 +} 1.53 + 1.54 +NS_IMETHODIMP 1.55 +nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) 1.56 +{ 1.57 + // don't override anything. 1.58 + *_retval = false; 1.59 + return NS_OK; 1.60 +} 1.61 + 1.62 +NS_IMETHODIMP 1.63 +nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result) 1.64 +{ 1.65 + *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE; 1.66 + return NS_OK; 1.67 +} 1.68 + 1.69 +NS_IMETHODIMP 1.70 +nsChromeProtocolHandler::NewURI(const nsACString &aSpec, 1.71 + const char *aCharset, 1.72 + nsIURI *aBaseURI, 1.73 + nsIURI **result) 1.74 +{ 1.75 + nsresult rv; 1.76 + 1.77 + // Chrome: URLs (currently) have no additional structure beyond that provided 1.78 + // by standard URLs, so there is no "outer" given to CreateInstance 1.79 + 1.80 + nsCOMPtr<nsIStandardURL> surl(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv)); 1.81 + NS_ENSURE_SUCCESS(rv, rv); 1.82 + 1.83 + rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI); 1.84 + if (NS_FAILED(rv)) 1.85 + return rv; 1.86 + 1.87 + nsCOMPtr<nsIURL> url(do_QueryInterface(surl, &rv)); 1.88 + NS_ENSURE_SUCCESS(rv, rv); 1.89 + 1.90 + // Canonify the "chrome:" URL; e.g., so that we collapse 1.91 + // "chrome://navigator/content/" and "chrome://navigator/content" 1.92 + // and "chrome://navigator/content/navigator.xul". 1.93 + 1.94 + rv = nsChromeRegistry::Canonify(url); 1.95 + if (NS_FAILED(rv)) 1.96 + return rv; 1.97 + 1.98 + surl->SetMutable(false); 1.99 + 1.100 + NS_ADDREF(*result = url); 1.101 + return NS_OK; 1.102 +} 1.103 + 1.104 +NS_IMETHODIMP 1.105 +nsChromeProtocolHandler::NewChannel(nsIURI* aURI, 1.106 + nsIChannel* *aResult) 1.107 +{ 1.108 + nsresult rv; 1.109 + 1.110 + NS_ENSURE_ARG_POINTER(aURI); 1.111 + NS_PRECONDITION(aResult, "Null out param"); 1.112 + 1.113 +#ifdef DEBUG 1.114 + // Check that the uri we got is already canonified 1.115 + nsresult debug_rv; 1.116 + nsCOMPtr<nsIURI> debugClone; 1.117 + debug_rv = aURI->Clone(getter_AddRefs(debugClone)); 1.118 + if (NS_SUCCEEDED(debug_rv)) { 1.119 + nsCOMPtr<nsIURL> debugURL (do_QueryInterface(debugClone)); 1.120 + debug_rv = nsChromeRegistry::Canonify(debugURL); 1.121 + if (NS_SUCCEEDED(debug_rv)) { 1.122 + bool same; 1.123 + debug_rv = aURI->Equals(debugURL, &same); 1.124 + if (NS_SUCCEEDED(debug_rv)) { 1.125 + NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!"); 1.126 + } 1.127 + } 1.128 + } 1.129 +#endif 1.130 + 1.131 + nsCOMPtr<nsIChannel> result; 1.132 + 1.133 + if (!nsChromeRegistry::gChromeRegistry) { 1.134 + // We don't actually want this ref, we just want the service to 1.135 + // initialize if it hasn't already. 1.136 + nsCOMPtr<nsIChromeRegistry> reg = 1.137 + mozilla::services::GetChromeRegistryService(); 1.138 + NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE); 1.139 + } 1.140 + 1.141 + nsCOMPtr<nsIURI> resolvedURI; 1.142 + rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); 1.143 + if (NS_FAILED(rv)) { 1.144 +#ifdef DEBUG 1.145 + nsAutoCString spec; 1.146 + aURI->GetSpec(spec); 1.147 + printf("Couldn't convert chrome URL: %s\n", spec.get()); 1.148 +#endif 1.149 + return rv; 1.150 + } 1.151 + 1.152 + nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); 1.153 + NS_ENSURE_SUCCESS(rv, rv); 1.154 + 1.155 + rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); 1.156 + if (NS_FAILED(rv)) return rv; 1.157 + 1.158 +#ifdef DEBUG 1.159 + nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result)); 1.160 + if (fileChan) { 1.161 + nsCOMPtr<nsIFile> file; 1.162 + fileChan->GetFile(getter_AddRefs(file)); 1.163 + 1.164 + bool exists = false; 1.165 + file->Exists(&exists); 1.166 + if (!exists) { 1.167 + nsAutoCString path; 1.168 + file->GetNativePath(path); 1.169 + printf("Chrome file doesn't exist: %s\n", path.get()); 1.170 + } 1.171 + } 1.172 +#endif 1.173 + 1.174 + // Make sure that the channel remembers where it was 1.175 + // originally loaded from. 1.176 + nsLoadFlags loadFlags = 0; 1.177 + result->GetLoadFlags(&loadFlags); 1.178 + result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE); 1.179 + rv = result->SetOriginalURI(aURI); 1.180 + if (NS_FAILED(rv)) return rv; 1.181 + 1.182 + // Get a system principal for content files and set the owner 1.183 + // property of the result 1.184 + nsCOMPtr<nsIURL> url = do_QueryInterface(aURI); 1.185 + nsAutoCString path; 1.186 + rv = url->GetPath(path); 1.187 + if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/"))) 1.188 + { 1.189 + nsCOMPtr<nsIScriptSecurityManager> securityManager = 1.190 + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); 1.191 + if (NS_FAILED(rv)) return rv; 1.192 + 1.193 + nsCOMPtr<nsIPrincipal> principal; 1.194 + rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal)); 1.195 + if (NS_FAILED(rv)) return rv; 1.196 + 1.197 + nsCOMPtr<nsISupports> owner = do_QueryInterface(principal); 1.198 + result->SetOwner(owner); 1.199 + } 1.200 + 1.201 + // XXX Removed dependency-tracking code from here, because we're not 1.202 + // tracking them anyways (with fastload we checked only in DEBUG 1.203 + // and with startupcache not at all), but this is where we would start 1.204 + // if we need to re-add. 1.205 + // See bug 531886, bug 533038. 1.206 + result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8")); 1.207 + 1.208 + *aResult = result; 1.209 + NS_ADDREF(*aResult); 1.210 + return NS_OK; 1.211 +} 1.212 + 1.213 +////////////////////////////////////////////////////////////////////////////////