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/. */
9 A protocol handler for ``chrome:''
13 #include "nsChromeProtocolHandler.h"
14 #include "nsChromeRegistry.h"
16 #include "nsContentUtils.h"
17 #include "nsThreadUtils.h"
18 #include "nsIChannel.h"
19 #include "nsIChromeRegistry.h"
21 #include "nsIFileChannel.h"
22 #include "nsIStandardURL.h"
23 #include "nsNetUtil.h"
27 #include "nsStandardURL.h"
29 ////////////////////////////////////////////////////////////////////////////////
31 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler
, nsIProtocolHandler
,
32 nsISupportsWeakReference
)
34 ////////////////////////////////////////////////////////////////////////////////
35 // nsIProtocolHandler methods:
38 nsChromeProtocolHandler::GetScheme(nsACString
& result
) {
39 result
.AssignLiteral("chrome");
44 nsChromeProtocolHandler::GetDefaultPort(int32_t* result
) {
45 *result
= -1; // no port for chrome: URLs
50 nsChromeProtocolHandler::AllowPort(int32_t port
, const char* scheme
,
52 // don't override anything.
58 nsChromeProtocolHandler::GetProtocolFlags(uint32_t* result
) {
59 *result
= URI_STD
| URI_IS_UI_RESOURCE
| URI_IS_LOCAL_RESOURCE
;
63 /* static */ nsresult
nsChromeProtocolHandler::CreateNewURI(
64 const nsACString
& aSpec
, const char* aCharset
, nsIURI
* aBaseURI
,
66 // Chrome: URLs (currently) have no additional structure beyond that provided
67 // by standard URLs, so there is no "outer" given to CreateInstance
69 nsCOMPtr
<nsIURI
> surl
;
70 nsCOMPtr
<nsIURI
> base(aBaseURI
);
71 rv
= NS_MutateURI(new mozilla::net::nsStandardURL::Mutator())
72 .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init
,
73 nsIStandardURL::URLTYPE_STANDARD
, -1,
74 nsCString(aSpec
), aCharset
, base
, nullptr))
80 // Canonify the "chrome:" URL; e.g., so that we collapse
81 // "chrome://navigator/content/" and "chrome://navigator/content"
82 // and "chrome://navigator/content/navigator.xul".
84 rv
= nsChromeRegistry::Canonify(surl
);
85 if (NS_FAILED(rv
)) return rv
;
92 nsChromeProtocolHandler::NewChannel(nsIURI
* aURI
, nsILoadInfo
* aLoadInfo
,
93 nsIChannel
** aResult
) {
96 NS_ENSURE_ARG_POINTER(aURI
);
97 NS_ENSURE_ARG_POINTER(aLoadInfo
);
99 MOZ_ASSERT(aResult
, "Null out param");
102 // Check that the uri we got is already canonified
104 nsCOMPtr
<nsIURI
> debugURL
= aURI
;
105 debug_rv
= nsChromeRegistry::Canonify(debugURL
);
106 if (NS_SUCCEEDED(debug_rv
)) {
108 debug_rv
= aURI
->Equals(debugURL
, &same
);
109 if (NS_SUCCEEDED(debug_rv
)) {
111 "Non-canonified chrome uri passed to "
112 "nsChromeProtocolHandler::NewChannel!");
117 nsCOMPtr
<nsIChannel
> result
;
119 if (!nsChromeRegistry::gChromeRegistry
) {
120 // We don't actually want this ref, we just want the service to
121 // initialize if it hasn't already.
122 nsCOMPtr
<nsIChromeRegistry
> reg
=
123 mozilla::services::GetChromeRegistryService();
124 NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry
, NS_ERROR_FAILURE
);
127 nsCOMPtr
<nsIURI
> resolvedURI
;
128 rv
= nsChromeRegistry::gChromeRegistry
->ConvertChromeURL(
129 aURI
, getter_AddRefs(resolvedURI
));
132 printf("Couldn't convert chrome URL: %s\n", aURI
->GetSpecOrDefault().get());
137 // We don't want to allow the inner protocol handler modify the result
138 // principal URI since we want either |aURI| or anything pre-set by upper
139 // layers to prevail.
140 nsCOMPtr
<nsIURI
> savedResultPrincipalURI
;
142 aLoadInfo
->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI
));
143 NS_ENSURE_SUCCESS(rv
, rv
);
145 rv
= NS_NewChannelInternal(getter_AddRefs(result
), resolvedURI
, aLoadInfo
);
146 NS_ENSURE_SUCCESS(rv
, rv
);
149 nsCOMPtr
<nsIFileChannel
> fileChan(do_QueryInterface(result
));
151 nsCOMPtr
<nsIFile
> file
;
152 fileChan
->GetFile(getter_AddRefs(file
));
155 file
->Exists(&exists
);
157 printf("Chrome file doesn't exist: %s\n",
158 file
->HumanReadablePath().get());
163 // Make sure that the channel remembers where it was
164 // originally loaded from.
165 rv
= aLoadInfo
->SetResultPrincipalURI(savedResultPrincipalURI
);
166 NS_ENSURE_SUCCESS(rv
, rv
);
167 rv
= result
->SetOriginalURI(aURI
);
168 if (NS_FAILED(rv
)) return rv
;
170 // Get a system principal for content files and set the owner
171 // property of the result
172 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(aURI
);
174 rv
= url
->GetPathQueryRef(path
);
175 if (StringBeginsWith(path
, NS_LITERAL_CSTRING("/content/"))) {
176 result
->SetOwner(nsContentUtils::GetSystemPrincipal());
179 // XXX Removed dependency-tracking code from here, because we're not
180 // tracking them anyways (with fastload we checked only in DEBUG
181 // and with startupcache not at all), but this is where we would start
182 // if we need to re-add.
183 // See bug 531886, bug 533038.
184 result
->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
191 ////////////////////////////////////////////////////////////////////////////////