Bug 1572460 - Refactor `selection` out of the `InspectorFront`. r=yulia
[gecko.git] / chrome / nsChromeProtocolHandler.cpp
blobbe7bb578f4d9ee4908634c3ba185260056a4cd2e
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/. */
7 /*
9 A protocol handler for ``chrome:''
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 "nsIIOService.h"
23 #include "nsILoadGroup.h"
24 #include "nsIScriptSecurityManager.h"
25 #include "nsIStandardURL.h"
26 #include "nsNetUtil.h"
27 #include "nsNetCID.h"
28 #include "nsIURL.h"
29 #include "nsString.h"
30 #include "nsStandardURL.h"
32 ////////////////////////////////////////////////////////////////////////////////
34 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler, nsIProtocolHandler,
35 nsISupportsWeakReference)
37 ////////////////////////////////////////////////////////////////////////////////
38 // nsIProtocolHandler methods:
40 NS_IMETHODIMP
41 nsChromeProtocolHandler::GetScheme(nsACString& result) {
42 result.AssignLiteral("chrome");
43 return NS_OK;
46 NS_IMETHODIMP
47 nsChromeProtocolHandler::GetDefaultPort(int32_t* result) {
48 *result = -1; // no port for chrome: URLs
49 return NS_OK;
52 NS_IMETHODIMP
53 nsChromeProtocolHandler::AllowPort(int32_t port, const char* scheme,
54 bool* _retval) {
55 // don't override anything.
56 *_retval = false;
57 return NS_OK;
60 NS_IMETHODIMP
61 nsChromeProtocolHandler::GetProtocolFlags(uint32_t* result) {
62 *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
63 return NS_OK;
66 /* static */ nsresult nsChromeProtocolHandler::CreateNewURI(
67 const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI,
68 nsIURI** result) {
69 // Chrome: URLs (currently) have no additional structure beyond that provided
70 // by standard URLs, so there is no "outer" given to CreateInstance
71 nsresult rv;
72 nsCOMPtr<nsIURI> surl;
73 nsCOMPtr<nsIURI> base(aBaseURI);
74 rv = NS_MutateURI(new mozilla::net::nsStandardURL::Mutator())
75 .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
76 nsIStandardURL::URLTYPE_STANDARD, -1,
77 nsCString(aSpec), aCharset, base, nullptr))
78 .Finalize(surl);
79 if (NS_FAILED(rv)) {
80 return rv;
83 // Canonify the "chrome:" URL; e.g., so that we collapse
84 // "chrome://navigator/content/" and "chrome://navigator/content"
85 // and "chrome://navigator/content/navigator.xul".
87 rv = nsChromeRegistry::Canonify(surl);
88 if (NS_FAILED(rv)) return rv;
90 surl.forget(result);
91 return NS_OK;
94 NS_IMETHODIMP
95 nsChromeProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
96 nsIChannel** aResult) {
97 nsresult rv;
99 NS_ENSURE_ARG_POINTER(aURI);
100 NS_ENSURE_ARG_POINTER(aLoadInfo);
102 MOZ_ASSERT(aResult, "Null out param");
104 #ifdef DEBUG
105 // Check that the uri we got is already canonified
106 nsresult debug_rv;
107 nsCOMPtr<nsIURI> debugURL = aURI;
108 debug_rv = nsChromeRegistry::Canonify(debugURL);
109 if (NS_SUCCEEDED(debug_rv)) {
110 bool same;
111 debug_rv = aURI->Equals(debugURL, &same);
112 if (NS_SUCCEEDED(debug_rv)) {
113 NS_ASSERTION(same,
114 "Non-canonified chrome uri passed to "
115 "nsChromeProtocolHandler::NewChannel!");
118 #endif
120 nsCOMPtr<nsIChannel> result;
122 if (!nsChromeRegistry::gChromeRegistry) {
123 // We don't actually want this ref, we just want the service to
124 // initialize if it hasn't already.
125 nsCOMPtr<nsIChromeRegistry> reg =
126 mozilla::services::GetChromeRegistryService();
127 NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
130 nsCOMPtr<nsIURI> resolvedURI;
131 rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(
132 aURI, getter_AddRefs(resolvedURI));
133 if (NS_FAILED(rv)) {
134 #ifdef DEBUG
135 printf("Couldn't convert chrome URL: %s\n", aURI->GetSpecOrDefault().get());
136 #endif
137 return rv;
140 // We don't want to allow the inner protocol handler modify the result
141 // principal URI since we want either |aURI| or anything pre-set by upper
142 // layers to prevail.
143 nsCOMPtr<nsIURI> savedResultPrincipalURI;
144 rv =
145 aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
146 NS_ENSURE_SUCCESS(rv, rv);
148 rv = NS_NewChannelInternal(getter_AddRefs(result), resolvedURI, aLoadInfo);
149 NS_ENSURE_SUCCESS(rv, rv);
151 #ifdef DEBUG
152 nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
153 if (fileChan) {
154 nsCOMPtr<nsIFile> file;
155 fileChan->GetFile(getter_AddRefs(file));
157 bool exists = false;
158 file->Exists(&exists);
159 if (!exists) {
160 printf("Chrome file doesn't exist: %s\n",
161 file->HumanReadablePath().get());
164 #endif
166 // Make sure that the channel remembers where it was
167 // originally loaded from.
168 rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
169 NS_ENSURE_SUCCESS(rv, rv);
170 rv = result->SetOriginalURI(aURI);
171 if (NS_FAILED(rv)) return rv;
173 // Get a system principal for content files and set the owner
174 // property of the result
175 nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
176 nsAutoCString path;
177 rv = url->GetPathQueryRef(path);
178 if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/"))) {
179 result->SetOwner(nsContentUtils::GetSystemPrincipal());
182 // XXX Removed dependency-tracking code from here, because we're not
183 // tracking them anyways (with fastload we checked only in DEBUG
184 // and with startupcache not at all), but this is where we would start
185 // if we need to re-add.
186 // See bug 531886, bug 533038.
187 result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
189 *aResult = result;
190 NS_ADDREF(*aResult);
191 return NS_OK;
194 ////////////////////////////////////////////////////////////////////////////////