summaryrefslogtreecommitdiffstats
path: root/chrome/nsChromeProtocolHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/nsChromeProtocolHandler.cpp')
-rw-r--r--chrome/nsChromeProtocolHandler.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/chrome/nsChromeProtocolHandler.cpp b/chrome/nsChromeProtocolHandler.cpp
new file mode 100644
index 000000000..f66c6d362
--- /dev/null
+++ b/chrome/nsChromeProtocolHandler.cpp
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et cin: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+
+ A protocol handler for ``chrome:''
+
+*/
+
+#include "nsChromeProtocolHandler.h"
+#include "nsChromeRegistry.h"
+#include "nsCOMPtr.h"
+#include "nsThreadUtils.h"
+#include "nsIChannel.h"
+#include "nsIChromeRegistry.h"
+#include "nsIFile.h"
+#include "nsIFileChannel.h"
+#include "nsIIOService.h"
+#include "nsILoadGroup.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsIStandardURL.h"
+#include "nsNetUtil.h"
+#include "nsNetCID.h"
+#include "nsIURL.h"
+#include "nsString.h"
+#include "nsStandardURL.h"
+
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS(nsChromeProtocolHandler,
+ nsIProtocolHandler,
+ nsISupportsWeakReference)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIProtocolHandler methods:
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::GetScheme(nsACString &result)
+{
+ result.AssignLiteral("chrome");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::GetDefaultPort(int32_t *result)
+{
+ *result = -1; // no port for chrome: URLs
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
+{
+ // don't override anything.
+ *_retval = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result)
+{
+ *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
+ const char *aCharset,
+ nsIURI *aBaseURI,
+ nsIURI **result)
+{
+
+ // Chrome: URLs (currently) have no additional structure beyond that provided
+ // by standard URLs, so there is no "outer" given to CreateInstance
+
+ RefPtr<mozilla::net::nsStandardURL> surl = new mozilla::net::nsStandardURL();
+
+ nsresult rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec,
+ aCharset, aBaseURI);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Canonify the "chrome:" URL; e.g., so that we collapse
+ // "chrome://navigator/content/" and "chrome://navigator/content"
+ // and "chrome://navigator/content/navigator.xul".
+
+ rv = nsChromeRegistry::Canonify(surl);
+ if (NS_FAILED(rv))
+ return rv;
+
+ surl->SetMutable(false);
+
+ surl.forget(result);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
+ nsILoadInfo* aLoadInfo,
+ nsIChannel** aResult)
+{
+ nsresult rv;
+
+ NS_ENSURE_ARG_POINTER(aURI);
+ NS_PRECONDITION(aResult, "Null out param");
+
+#ifdef DEBUG
+ // Check that the uri we got is already canonified
+ nsresult debug_rv;
+ nsCOMPtr<nsIURI> debugClone;
+ debug_rv = aURI->Clone(getter_AddRefs(debugClone));
+ if (NS_SUCCEEDED(debug_rv)) {
+ nsCOMPtr<nsIURL> debugURL (do_QueryInterface(debugClone));
+ debug_rv = nsChromeRegistry::Canonify(debugURL);
+ if (NS_SUCCEEDED(debug_rv)) {
+ bool same;
+ debug_rv = aURI->Equals(debugURL, &same);
+ if (NS_SUCCEEDED(debug_rv)) {
+ NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
+ }
+ }
+ }
+#endif
+
+ nsCOMPtr<nsIChannel> result;
+
+ if (!nsChromeRegistry::gChromeRegistry) {
+ // We don't actually want this ref, we just want the service to
+ // initialize if it hasn't already.
+ nsCOMPtr<nsIChromeRegistry> reg =
+ mozilla::services::GetChromeRegistryService();
+ NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
+ }
+
+ nsCOMPtr<nsIURI> resolvedURI;
+ rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
+ if (NS_FAILED(rv)) {
+#ifdef DEBUG
+ printf("Couldn't convert chrome URL: %s\n",
+ aURI->GetSpecOrDefault().get());
+#endif
+ return rv;
+ }
+
+ rv = NS_NewChannelInternal(getter_AddRefs(result),
+ resolvedURI,
+ aLoadInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef DEBUG
+ nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
+ if (fileChan) {
+ nsCOMPtr<nsIFile> file;
+ fileChan->GetFile(getter_AddRefs(file));
+
+ bool exists = false;
+ file->Exists(&exists);
+ if (!exists) {
+ nsAutoCString path;
+ file->GetNativePath(path);
+ printf("Chrome file doesn't exist: %s\n", path.get());
+ }
+ }
+#endif
+
+ // Make sure that the channel remembers where it was
+ // originally loaded from.
+ nsLoadFlags loadFlags = 0;
+ result->GetLoadFlags(&loadFlags);
+ result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
+ rv = result->SetOriginalURI(aURI);
+ if (NS_FAILED(rv)) return rv;
+
+ // Get a system principal for content files and set the owner
+ // property of the result
+ nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
+ nsAutoCString path;
+ rv = url->GetPath(path);
+ if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/")))
+ {
+ nsCOMPtr<nsIScriptSecurityManager> securityManager =
+ do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIPrincipal> principal;
+ rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsISupports> owner = do_QueryInterface(principal);
+ result->SetOwner(owner);
+ }
+
+ // XXX Removed dependency-tracking code from here, because we're not
+ // tracking them anyways (with fastload we checked only in DEBUG
+ // and with startupcache not at all), but this is where we would start
+ // if we need to re-add.
+ // See bug 531886, bug 533038.
+ result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
+
+ *aResult = result;
+ NS_ADDREF(*aResult);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
+ nsIChannel* *aResult)
+{
+ return NewChannel2(aURI, nullptr, aResult);
+}
+
+////////////////////////////////////////////////////////////////////////////////