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 "nsThreadUtils.h"
17 #include "nsIChannel.h"
18 #include "nsIChromeRegistry.h"
20 #include "nsIFileChannel.h"
21 #include "nsIIOService.h"
22 #include "nsILoadGroup.h"
23 #include "nsIScriptSecurityManager.h"
24 #include "nsIStandardURL.h"
25 #include "nsNetUtil.h"
28 ////////////////////////////////////////////////////////////////////////////////
30 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler
,
32 nsISupportsWeakReference
)
34 ////////////////////////////////////////////////////////////////////////////////
35 // nsIProtocolHandler methods:
38 nsChromeProtocolHandler::GetScheme(nsACString
&result
)
40 result
.AssignLiteral("chrome");
45 nsChromeProtocolHandler::GetDefaultPort(int32_t *result
)
47 *result
= -1; // no port for chrome: URLs
52 nsChromeProtocolHandler::AllowPort(int32_t port
, const char *scheme
, bool *_retval
)
54 // don't override anything.
60 nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result
)
62 *result
= URI_STD
| URI_IS_UI_RESOURCE
| URI_IS_LOCAL_RESOURCE
;
67 nsChromeProtocolHandler::NewURI(const nsACString
&aSpec
,
74 // Chrome: URLs (currently) have no additional structure beyond that provided
75 // by standard URLs, so there is no "outer" given to CreateInstance
77 nsCOMPtr
<nsIStandardURL
> surl(do_CreateInstance(NS_STANDARDURL_CONTRACTID
, &rv
));
78 NS_ENSURE_SUCCESS(rv
, rv
);
80 rv
= surl
->Init(nsIStandardURL::URLTYPE_STANDARD
, -1, aSpec
, aCharset
, aBaseURI
);
84 nsCOMPtr
<nsIURL
> url(do_QueryInterface(surl
, &rv
));
85 NS_ENSURE_SUCCESS(rv
, rv
);
87 // Canonify the "chrome:" URL; e.g., so that we collapse
88 // "chrome://navigator/content/" and "chrome://navigator/content"
89 // and "chrome://navigator/content/navigator.xul".
91 rv
= nsChromeRegistry::Canonify(url
);
95 surl
->SetMutable(false);
97 NS_ADDREF(*result
= url
);
102 nsChromeProtocolHandler::NewChannel(nsIURI
* aURI
,
103 nsIChannel
* *aResult
)
107 NS_ENSURE_ARG_POINTER(aURI
);
108 NS_PRECONDITION(aResult
, "Null out param");
111 // Check that the uri we got is already canonified
113 nsCOMPtr
<nsIURI
> debugClone
;
114 debug_rv
= aURI
->Clone(getter_AddRefs(debugClone
));
115 if (NS_SUCCEEDED(debug_rv
)) {
116 nsCOMPtr
<nsIURL
> debugURL (do_QueryInterface(debugClone
));
117 debug_rv
= nsChromeRegistry::Canonify(debugURL
);
118 if (NS_SUCCEEDED(debug_rv
)) {
120 debug_rv
= aURI
->Equals(debugURL
, &same
);
121 if (NS_SUCCEEDED(debug_rv
)) {
122 NS_ASSERTION(same
, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
128 nsCOMPtr
<nsIChannel
> result
;
130 if (!nsChromeRegistry::gChromeRegistry
) {
131 // We don't actually want this ref, we just want the service to
132 // initialize if it hasn't already.
133 nsCOMPtr
<nsIChromeRegistry
> reg
=
134 mozilla::services::GetChromeRegistryService();
135 NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry
, NS_ERROR_FAILURE
);
138 nsCOMPtr
<nsIURI
> resolvedURI
;
139 rv
= nsChromeRegistry::gChromeRegistry
->ConvertChromeURL(aURI
, getter_AddRefs(resolvedURI
));
144 printf("Couldn't convert chrome URL: %s\n", spec
.get());
149 nsCOMPtr
<nsIIOService
> ioServ(do_GetIOService(&rv
));
150 NS_ENSURE_SUCCESS(rv
, rv
);
152 rv
= ioServ
->NewChannelFromURI(resolvedURI
, getter_AddRefs(result
));
153 if (NS_FAILED(rv
)) return rv
;
156 nsCOMPtr
<nsIFileChannel
> fileChan(do_QueryInterface(result
));
158 nsCOMPtr
<nsIFile
> file
;
159 fileChan
->GetFile(getter_AddRefs(file
));
162 file
->Exists(&exists
);
165 file
->GetNativePath(path
);
166 printf("Chrome file doesn't exist: %s\n", path
.get());
171 // Make sure that the channel remembers where it was
172 // originally loaded from.
173 nsLoadFlags loadFlags
= 0;
174 result
->GetLoadFlags(&loadFlags
);
175 result
->SetLoadFlags(loadFlags
& ~nsIChannel::LOAD_REPLACE
);
176 rv
= result
->SetOriginalURI(aURI
);
177 if (NS_FAILED(rv
)) return rv
;
179 // Get a system principal for content files and set the owner
180 // property of the result
181 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(aURI
);
183 rv
= url
->GetPath(path
);
184 if (StringBeginsWith(path
, NS_LITERAL_CSTRING("/content/")))
186 nsCOMPtr
<nsIScriptSecurityManager
> securityManager
=
187 do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID
, &rv
);
188 if (NS_FAILED(rv
)) return rv
;
190 nsCOMPtr
<nsIPrincipal
> principal
;
191 rv
= securityManager
->GetSystemPrincipal(getter_AddRefs(principal
));
192 if (NS_FAILED(rv
)) return rv
;
194 nsCOMPtr
<nsISupports
> owner
= do_QueryInterface(principal
);
195 result
->SetOwner(owner
);
198 // XXX Removed dependency-tracking code from here, because we're not
199 // tracking them anyways (with fastload we checked only in DEBUG
200 // and with startupcache not at all), but this is where we would start
201 // if we need to re-add.
202 // See bug 531886, bug 533038.
203 result
->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
210 ////////////////////////////////////////////////////////////////////////////////