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/. */
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 "nsIIOService.h"
23 #include "nsILoadGroup.h"
24 #include "nsIScriptSecurityManager.h"
25 #include "nsIStandardURL.h"
26 #include "nsNetUtil.h"
30 #include "nsStandardURL.h"
32 ////////////////////////////////////////////////////////////////////////////////
34 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler
,
36 nsISupportsWeakReference
)
38 ////////////////////////////////////////////////////////////////////////////////
39 // nsIProtocolHandler methods:
42 nsChromeProtocolHandler::GetScheme(nsACString
&result
)
44 result
.AssignLiteral("chrome");
49 nsChromeProtocolHandler::GetDefaultPort(int32_t *result
)
51 *result
= -1; // no port for chrome: URLs
56 nsChromeProtocolHandler::AllowPort(int32_t port
, const char *scheme
, bool *_retval
)
58 // don't override anything.
64 nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result
)
66 *result
= URI_STD
| URI_IS_UI_RESOURCE
| URI_IS_LOCAL_RESOURCE
;
71 nsChromeProtocolHandler::NewURI(const nsACString
&aSpec
,
77 // Chrome: URLs (currently) have no additional structure beyond that provided
78 // by standard URLs, so there is no "outer" given to CreateInstance
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
,
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
);
105 nsChromeProtocolHandler::NewChannel2(nsIURI
* aURI
,
106 nsILoadInfo
* aLoadInfo
,
107 nsIChannel
** aResult
)
111 NS_ENSURE_ARG_POINTER(aURI
);
112 NS_ENSURE_ARG_POINTER(aLoadInfo
);
114 MOZ_ASSERT(aResult
, "Null out param");
117 // Check that the uri we got is already canonified
119 nsCOMPtr
<nsIURI
> debugURL
= aURI
;
120 debug_rv
= nsChromeRegistry::Canonify(debugURL
);
121 if (NS_SUCCEEDED(debug_rv
)) {
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!");
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
));
144 printf("Couldn't convert chrome URL: %s\n",
145 aURI
->GetSpecOrDefault().get());
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
),
159 NS_ENSURE_SUCCESS(rv
, rv
);
162 nsCOMPtr
<nsIFileChannel
> fileChan(do_QueryInterface(result
));
164 nsCOMPtr
<nsIFile
> file
;
165 fileChan
->GetFile(getter_AddRefs(file
));
168 file
->Exists(&exists
);
170 printf("Chrome file doesn't exist: %s\n",
171 file
->HumanReadablePath().get());
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
);
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"));
205 nsChromeProtocolHandler::NewChannel(nsIURI
* aURI
,
206 nsIChannel
* *aResult
)
208 return NewChannel2(aURI
, nullptr, aResult
);
211 ////////////////////////////////////////////////////////////////////////////////