Bug 1492908 [wpt PR 13122] - Update wpt metadata, a=testonly
[gecko.git] / chrome / nsChromeProtocolHandler.cpp
blob1f1f1365df2e1815a9c54863adca51846dce156c
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:''
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,
35 nsIProtocolHandler,
36 nsISupportsWeakReference)
38 ////////////////////////////////////////////////////////////////////////////////
39 // nsIProtocolHandler methods:
41 NS_IMETHODIMP
42 nsChromeProtocolHandler::GetScheme(nsACString &result)
44 result.AssignLiteral("chrome");
45 return NS_OK;
48 NS_IMETHODIMP
49 nsChromeProtocolHandler::GetDefaultPort(int32_t *result)
51 *result = -1; // no port for chrome: URLs
52 return NS_OK;
55 NS_IMETHODIMP
56 nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
58 // don't override anything.
59 *_retval = false;
60 return NS_OK;
63 NS_IMETHODIMP
64 nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result)
66 *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
67 return NS_OK;
70 NS_IMETHODIMP
71 nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
72 const char *aCharset,
73 nsIURI *aBaseURI,
74 nsIURI **result)
77 // Chrome: URLs (currently) have no additional structure beyond that provided
78 // by standard URLs, so there is no "outer" given to CreateInstance
79 nsresult rv;
80 nsCOMPtr<nsIURI> surl;
81 nsCOMPtr<nsIURI> base(aBaseURI);
82 rv = NS_MutateURI(new mozilla::net::nsStandardURL::Mutator())
83 .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
84 nsIStandardURL::URLTYPE_STANDARD,
85 -1, nsCString(aSpec), aCharset,
86 base, nullptr))
87 .Finalize(surl);
88 if (NS_FAILED(rv)) {
89 return rv;
92 // Canonify the "chrome:" URL; e.g., so that we collapse
93 // "chrome://navigator/content/" and "chrome://navigator/content"
94 // and "chrome://navigator/content/navigator.xul".
96 rv = nsChromeRegistry::Canonify(surl);
97 if (NS_FAILED(rv))
98 return rv;
100 surl.forget(result);
101 return NS_OK;
104 NS_IMETHODIMP
105 nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
106 nsILoadInfo* aLoadInfo,
107 nsIChannel** aResult)
109 nsresult rv;
111 NS_ENSURE_ARG_POINTER(aURI);
112 NS_ENSURE_ARG_POINTER(aLoadInfo);
114 MOZ_ASSERT(aResult, "Null out param");
116 #ifdef DEBUG
117 // Check that the uri we got is already canonified
118 nsresult debug_rv;
119 nsCOMPtr<nsIURI> debugURL = aURI;
120 debug_rv = nsChromeRegistry::Canonify(debugURL);
121 if (NS_SUCCEEDED(debug_rv)) {
122 bool same;
123 debug_rv = aURI->Equals(debugURL, &same);
124 if (NS_SUCCEEDED(debug_rv)) {
125 NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
128 #endif
130 nsCOMPtr<nsIChannel> result;
132 if (!nsChromeRegistry::gChromeRegistry) {
133 // We don't actually want this ref, we just want the service to
134 // initialize if it hasn't already.
135 nsCOMPtr<nsIChromeRegistry> reg =
136 mozilla::services::GetChromeRegistryService();
137 NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
140 nsCOMPtr<nsIURI> resolvedURI;
141 rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
142 if (NS_FAILED(rv)) {
143 #ifdef DEBUG
144 printf("Couldn't convert chrome URL: %s\n",
145 aURI->GetSpecOrDefault().get());
146 #endif
147 return rv;
150 // We don't want to allow the inner protocol handler modify the result principal URI
151 // since we want either |aURI| or anything pre-set by upper layers to prevail.
152 nsCOMPtr<nsIURI> savedResultPrincipalURI;
153 rv = aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
154 NS_ENSURE_SUCCESS(rv, rv);
156 rv = NS_NewChannelInternal(getter_AddRefs(result),
157 resolvedURI,
158 aLoadInfo);
159 NS_ENSURE_SUCCESS(rv, rv);
161 #ifdef DEBUG
162 nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
163 if (fileChan) {
164 nsCOMPtr<nsIFile> file;
165 fileChan->GetFile(getter_AddRefs(file));
167 bool exists = false;
168 file->Exists(&exists);
169 if (!exists) {
170 printf("Chrome file doesn't exist: %s\n",
171 file->HumanReadablePath().get());
174 #endif
176 // Make sure that the channel remembers where it was
177 // originally loaded from.
178 rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
179 NS_ENSURE_SUCCESS(rv, rv);
180 rv = result->SetOriginalURI(aURI);
181 if (NS_FAILED(rv)) return rv;
183 // Get a system principal for content files and set the owner
184 // property of the result
185 nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
186 nsAutoCString path;
187 rv = url->GetPathQueryRef(path);
188 if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/"))) {
189 result->SetOwner(nsContentUtils::GetSystemPrincipal());
192 // XXX Removed dependency-tracking code from here, because we're not
193 // tracking them anyways (with fastload we checked only in DEBUG
194 // and with startupcache not at all), but this is where we would start
195 // if we need to re-add.
196 // See bug 531886, bug 533038.
197 result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
199 *aResult = result;
200 NS_ADDREF(*aResult);
201 return NS_OK;
204 NS_IMETHODIMP
205 nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
206 nsIChannel* *aResult)
208 return NewChannel2(aURI, nullptr, aResult);
211 ////////////////////////////////////////////////////////////////////////////////