Backed out changeset 67f13af428e3 (bug 1877703) for causing crashes and assertion...
[gecko.git] / chrome / nsChromeProtocolHandler.cpp
blobb2e1e4d361deab9d204b3b7ad3f547dfdc1f0087
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 "nsIStandardURL.h"
23 #include "nsNetUtil.h"
24 #include "nsNetCID.h"
25 #include "nsIURL.h"
26 #include "nsString.h"
27 #include "nsStandardURL.h"
29 ////////////////////////////////////////////////////////////////////////////////
31 NS_IMPL_ISUPPORTS(nsChromeProtocolHandler, nsIProtocolHandler,
32 nsISupportsWeakReference)
34 ////////////////////////////////////////////////////////////////////////////////
35 // nsIProtocolHandler methods:
37 NS_IMETHODIMP
38 nsChromeProtocolHandler::GetScheme(nsACString& result) {
39 result.AssignLiteral("chrome");
40 return NS_OK;
43 NS_IMETHODIMP
44 nsChromeProtocolHandler::AllowPort(int32_t port, const char* scheme,
45 bool* _retval) {
46 // don't override anything.
47 *_retval = false;
48 return NS_OK;
51 /* static */ nsresult nsChromeProtocolHandler::CreateNewURI(
52 const nsACString& aSpec, const char* aCharset, nsIURI* aBaseURI,
53 nsIURI** result) {
54 // Chrome: URLs (currently) have no additional structure beyond that provided
55 // by standard URLs, so there is no "outer" given to CreateInstance
56 nsresult rv;
57 nsCOMPtr<nsIURI> surl;
58 rv =
59 NS_MutateURI(new mozilla::net::nsStandardURL::Mutator())
60 .Apply(&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_STANDARD,
61 -1, aSpec, aCharset, aBaseURI, nullptr)
63 .Finalize(surl);
64 if (NS_FAILED(rv)) {
65 return rv;
68 // Canonify the "chrome:" URL; e.g., so that we collapse
69 // "chrome://navigator/content/" and "chrome://navigator/content"
70 // and "chrome://navigator/content/navigator.xul".
72 rv = nsChromeRegistry::Canonify(surl);
73 mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
75 surl.forget(result);
76 return NS_OK;
79 NS_IMETHODIMP
80 nsChromeProtocolHandler::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
81 nsIChannel** aResult) {
82 nsresult rv;
84 NS_ENSURE_ARG_POINTER(aURI);
85 NS_ENSURE_ARG_POINTER(aLoadInfo);
87 MOZ_ASSERT(aResult, "Null out param");
89 nsCOMPtr<nsIURI> debugURL = aURI;
90 rv = nsChromeRegistry::Canonify(debugURL);
91 NS_ENSURE_SUCCESS(rv, rv);
93 nsCOMPtr<nsIChannel> result;
95 if (!nsChromeRegistry::gChromeRegistry) {
96 // We don't actually want this ref, we just want the service to
97 // initialize if it hasn't already.
98 nsCOMPtr<nsIChromeRegistry> reg = mozilla::services::GetChromeRegistry();
99 NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
102 nsCOMPtr<nsIURI> resolvedURI;
103 rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(
104 aURI, getter_AddRefs(resolvedURI));
105 if (NS_FAILED(rv)) {
106 #ifdef DEBUG
107 printf("Couldn't convert chrome URL: %s\n", aURI->GetSpecOrDefault().get());
108 #endif
109 return rv;
112 // We don't want to allow the inner protocol handler modify the result
113 // principal URI since we want either |aURI| or anything pre-set by upper
114 // layers to prevail.
115 nsCOMPtr<nsIURI> savedResultPrincipalURI;
116 rv =
117 aLoadInfo->GetResultPrincipalURI(getter_AddRefs(savedResultPrincipalURI));
118 NS_ENSURE_SUCCESS(rv, rv);
120 rv = NS_NewChannelInternal(getter_AddRefs(result), resolvedURI, aLoadInfo);
121 NS_ENSURE_SUCCESS(rv, rv);
123 #ifdef DEBUG
124 nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
125 if (fileChan) {
126 nsCOMPtr<nsIFile> file;
127 fileChan->GetFile(getter_AddRefs(file));
129 bool exists = false;
130 file->Exists(&exists);
131 if (!exists) {
132 printf("Chrome file doesn't exist: %s\n",
133 file->HumanReadablePath().get());
136 #endif
138 // Make sure that the channel remembers where it was
139 // originally loaded from.
140 rv = aLoadInfo->SetResultPrincipalURI(savedResultPrincipalURI);
141 NS_ENSURE_SUCCESS(rv, rv);
142 rv = result->SetOriginalURI(aURI);
143 if (NS_FAILED(rv)) return rv;
145 // Use a system principal for /content and /skin files.
146 // See bug 1855225 for discussion about whether to extend it more generally
147 // to other chrome:// URIs.
148 nsAutoCString path;
149 aURI->GetPathQueryRef(path);
150 if (StringBeginsWith(path, "/content/"_ns) ||
151 StringBeginsWith(path, "/skin/"_ns)) {
152 result->SetOwner(nsContentUtils::GetSystemPrincipal());
155 // XXX Removed dependency-tracking code from here, because we're not
156 // tracking them anyways (with fastload we checked only in DEBUG
157 // and with startupcache not at all), but this is where we would start
158 // if we need to re-add.
159 // See bug 531886, bug 533038.
160 result->SetContentCharset("UTF-8"_ns);
162 result.forget(aResult);
163 return NS_OK;
166 ////////////////////////////////////////////////////////////////////////////////