nsChromeProtocolHandler.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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/. */
  6. /*
  7. A protocol handler for ``chrome:''
  8. */
  9. #include "nsChromeProtocolHandler.h"
  10. #include "nsChromeRegistry.h"
  11. #include "nsCOMPtr.h"
  12. #include "nsThreadUtils.h"
  13. #include "nsIChannel.h"
  14. #include "nsIChromeRegistry.h"
  15. #include "nsIFile.h"
  16. #include "nsIFileChannel.h"
  17. #include "nsIIOService.h"
  18. #include "nsILoadGroup.h"
  19. #include "nsIScriptSecurityManager.h"
  20. #include "nsIStandardURL.h"
  21. #include "nsNetUtil.h"
  22. #include "nsNetCID.h"
  23. #include "nsIURL.h"
  24. #include "nsString.h"
  25. #include "nsStandardURL.h"
  26. ////////////////////////////////////////////////////////////////////////////////
  27. NS_IMPL_ISUPPORTS(nsChromeProtocolHandler,
  28. nsIProtocolHandler,
  29. nsISupportsWeakReference)
  30. ////////////////////////////////////////////////////////////////////////////////
  31. // nsIProtocolHandler methods:
  32. NS_IMETHODIMP
  33. nsChromeProtocolHandler::GetScheme(nsACString &result)
  34. {
  35. result.AssignLiteral("chrome");
  36. return NS_OK;
  37. }
  38. NS_IMETHODIMP
  39. nsChromeProtocolHandler::GetDefaultPort(int32_t *result)
  40. {
  41. *result = -1; // no port for chrome: URLs
  42. return NS_OK;
  43. }
  44. NS_IMETHODIMP
  45. nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval)
  46. {
  47. // don't override anything.
  48. *_retval = false;
  49. return NS_OK;
  50. }
  51. NS_IMETHODIMP
  52. nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result)
  53. {
  54. *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
  55. return NS_OK;
  56. }
  57. NS_IMETHODIMP
  58. nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
  59. const char *aCharset,
  60. nsIURI *aBaseURI,
  61. nsIURI **result)
  62. {
  63. // Chrome: URLs (currently) have no additional structure beyond that provided
  64. // by standard URLs, so there is no "outer" given to CreateInstance
  65. RefPtr<mozilla::net::nsStandardURL> surl = new mozilla::net::nsStandardURL();
  66. nsresult rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec,
  67. aCharset, aBaseURI);
  68. if (NS_FAILED(rv))
  69. return rv;
  70. // Canonify the "chrome:" URL; e.g., so that we collapse
  71. // "chrome://navigator/content/" and "chrome://navigator/content"
  72. // and "chrome://navigator/content/navigator.xul".
  73. rv = nsChromeRegistry::Canonify(surl);
  74. if (NS_FAILED(rv))
  75. return rv;
  76. surl->SetMutable(false);
  77. surl.forget(result);
  78. return NS_OK;
  79. }
  80. NS_IMETHODIMP
  81. nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
  82. nsILoadInfo* aLoadInfo,
  83. nsIChannel** aResult)
  84. {
  85. nsresult rv;
  86. NS_ENSURE_ARG_POINTER(aURI);
  87. NS_PRECONDITION(aResult, "Null out param");
  88. #ifdef DEBUG
  89. // Check that the uri we got is already canonified
  90. nsresult debug_rv;
  91. nsCOMPtr<nsIURI> debugClone;
  92. debug_rv = aURI->Clone(getter_AddRefs(debugClone));
  93. if (NS_SUCCEEDED(debug_rv)) {
  94. nsCOMPtr<nsIURL> debugURL (do_QueryInterface(debugClone));
  95. debug_rv = nsChromeRegistry::Canonify(debugURL);
  96. if (NS_SUCCEEDED(debug_rv)) {
  97. bool same;
  98. debug_rv = aURI->Equals(debugURL, &same);
  99. if (NS_SUCCEEDED(debug_rv)) {
  100. NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!");
  101. }
  102. }
  103. }
  104. #endif
  105. nsCOMPtr<nsIChannel> result;
  106. if (!nsChromeRegistry::gChromeRegistry) {
  107. // We don't actually want this ref, we just want the service to
  108. // initialize if it hasn't already.
  109. nsCOMPtr<nsIChromeRegistry> reg =
  110. mozilla::services::GetChromeRegistryService();
  111. NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE);
  112. }
  113. nsCOMPtr<nsIURI> resolvedURI;
  114. rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI));
  115. if (NS_FAILED(rv)) {
  116. #ifdef DEBUG
  117. printf("Couldn't convert chrome URL: %s\n",
  118. aURI->GetSpecOrDefault().get());
  119. #endif
  120. return rv;
  121. }
  122. rv = NS_NewChannelInternal(getter_AddRefs(result),
  123. resolvedURI,
  124. aLoadInfo);
  125. NS_ENSURE_SUCCESS(rv, rv);
  126. #ifdef DEBUG
  127. nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result));
  128. if (fileChan) {
  129. nsCOMPtr<nsIFile> file;
  130. fileChan->GetFile(getter_AddRefs(file));
  131. bool exists = false;
  132. file->Exists(&exists);
  133. if (!exists) {
  134. nsAutoCString path;
  135. file->GetNativePath(path);
  136. printf("Chrome file doesn't exist: %s\n", path.get());
  137. }
  138. }
  139. #endif
  140. // Make sure that the channel remembers where it was
  141. // originally loaded from.
  142. nsLoadFlags loadFlags = 0;
  143. result->GetLoadFlags(&loadFlags);
  144. result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
  145. rv = result->SetOriginalURI(aURI);
  146. if (NS_FAILED(rv)) return rv;
  147. // Get a system principal for content files and set the owner
  148. // property of the result
  149. nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
  150. nsAutoCString path;
  151. rv = url->GetPath(path);
  152. if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/")))
  153. {
  154. nsCOMPtr<nsIScriptSecurityManager> securityManager =
  155. do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
  156. if (NS_FAILED(rv)) return rv;
  157. nsCOMPtr<nsIPrincipal> principal;
  158. rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
  159. if (NS_FAILED(rv)) return rv;
  160. nsCOMPtr<nsISupports> owner = do_QueryInterface(principal);
  161. result->SetOwner(owner);
  162. }
  163. // XXX Removed dependency-tracking code from here, because we're not
  164. // tracking them anyways (with fastload we checked only in DEBUG
  165. // and with startupcache not at all), but this is where we would start
  166. // if we need to re-add.
  167. // See bug 531886, bug 533038.
  168. result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8"));
  169. *aResult = result;
  170. NS_ADDREF(*aResult);
  171. return NS_OK;
  172. }
  173. NS_IMETHODIMP
  174. nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
  175. nsIChannel* *aResult)
  176. {
  177. return NewChannel2(aURI, nullptr, aResult);
  178. }
  179. ////////////////////////////////////////////////////////////////////////////////