Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* vim:set ts=4 sw=4 sts=4 et cin: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /* |
michael@0 | 8 | |
michael@0 | 9 | A protocol handler for ``chrome:'' |
michael@0 | 10 | |
michael@0 | 11 | */ |
michael@0 | 12 | |
michael@0 | 13 | #include "nsChromeProtocolHandler.h" |
michael@0 | 14 | #include "nsChromeRegistry.h" |
michael@0 | 15 | #include "nsCOMPtr.h" |
michael@0 | 16 | #include "nsThreadUtils.h" |
michael@0 | 17 | #include "nsIChannel.h" |
michael@0 | 18 | #include "nsIChromeRegistry.h" |
michael@0 | 19 | #include "nsIFile.h" |
michael@0 | 20 | #include "nsIFileChannel.h" |
michael@0 | 21 | #include "nsIIOService.h" |
michael@0 | 22 | #include "nsILoadGroup.h" |
michael@0 | 23 | #include "nsIScriptSecurityManager.h" |
michael@0 | 24 | #include "nsIStandardURL.h" |
michael@0 | 25 | #include "nsNetUtil.h" |
michael@0 | 26 | #include "nsString.h" |
michael@0 | 27 | |
michael@0 | 28 | //////////////////////////////////////////////////////////////////////////////// |
michael@0 | 29 | |
michael@0 | 30 | NS_IMPL_ISUPPORTS(nsChromeProtocolHandler, |
michael@0 | 31 | nsIProtocolHandler, |
michael@0 | 32 | nsISupportsWeakReference) |
michael@0 | 33 | |
michael@0 | 34 | //////////////////////////////////////////////////////////////////////////////// |
michael@0 | 35 | // nsIProtocolHandler methods: |
michael@0 | 36 | |
michael@0 | 37 | NS_IMETHODIMP |
michael@0 | 38 | nsChromeProtocolHandler::GetScheme(nsACString &result) |
michael@0 | 39 | { |
michael@0 | 40 | result.AssignLiteral("chrome"); |
michael@0 | 41 | return NS_OK; |
michael@0 | 42 | } |
michael@0 | 43 | |
michael@0 | 44 | NS_IMETHODIMP |
michael@0 | 45 | nsChromeProtocolHandler::GetDefaultPort(int32_t *result) |
michael@0 | 46 | { |
michael@0 | 47 | *result = -1; // no port for chrome: URLs |
michael@0 | 48 | return NS_OK; |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | NS_IMETHODIMP |
michael@0 | 52 | nsChromeProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *_retval) |
michael@0 | 53 | { |
michael@0 | 54 | // don't override anything. |
michael@0 | 55 | *_retval = false; |
michael@0 | 56 | return NS_OK; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | NS_IMETHODIMP |
michael@0 | 60 | nsChromeProtocolHandler::GetProtocolFlags(uint32_t *result) |
michael@0 | 61 | { |
michael@0 | 62 | *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE; |
michael@0 | 63 | return NS_OK; |
michael@0 | 64 | } |
michael@0 | 65 | |
michael@0 | 66 | NS_IMETHODIMP |
michael@0 | 67 | nsChromeProtocolHandler::NewURI(const nsACString &aSpec, |
michael@0 | 68 | const char *aCharset, |
michael@0 | 69 | nsIURI *aBaseURI, |
michael@0 | 70 | nsIURI **result) |
michael@0 | 71 | { |
michael@0 | 72 | nsresult rv; |
michael@0 | 73 | |
michael@0 | 74 | // Chrome: URLs (currently) have no additional structure beyond that provided |
michael@0 | 75 | // by standard URLs, so there is no "outer" given to CreateInstance |
michael@0 | 76 | |
michael@0 | 77 | nsCOMPtr<nsIStandardURL> surl(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv)); |
michael@0 | 78 | NS_ENSURE_SUCCESS(rv, rv); |
michael@0 | 79 | |
michael@0 | 80 | rv = surl->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI); |
michael@0 | 81 | if (NS_FAILED(rv)) |
michael@0 | 82 | return rv; |
michael@0 | 83 | |
michael@0 | 84 | nsCOMPtr<nsIURL> url(do_QueryInterface(surl, &rv)); |
michael@0 | 85 | NS_ENSURE_SUCCESS(rv, rv); |
michael@0 | 86 | |
michael@0 | 87 | // Canonify the "chrome:" URL; e.g., so that we collapse |
michael@0 | 88 | // "chrome://navigator/content/" and "chrome://navigator/content" |
michael@0 | 89 | // and "chrome://navigator/content/navigator.xul". |
michael@0 | 90 | |
michael@0 | 91 | rv = nsChromeRegistry::Canonify(url); |
michael@0 | 92 | if (NS_FAILED(rv)) |
michael@0 | 93 | return rv; |
michael@0 | 94 | |
michael@0 | 95 | surl->SetMutable(false); |
michael@0 | 96 | |
michael@0 | 97 | NS_ADDREF(*result = url); |
michael@0 | 98 | return NS_OK; |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | NS_IMETHODIMP |
michael@0 | 102 | nsChromeProtocolHandler::NewChannel(nsIURI* aURI, |
michael@0 | 103 | nsIChannel* *aResult) |
michael@0 | 104 | { |
michael@0 | 105 | nsresult rv; |
michael@0 | 106 | |
michael@0 | 107 | NS_ENSURE_ARG_POINTER(aURI); |
michael@0 | 108 | NS_PRECONDITION(aResult, "Null out param"); |
michael@0 | 109 | |
michael@0 | 110 | #ifdef DEBUG |
michael@0 | 111 | // Check that the uri we got is already canonified |
michael@0 | 112 | nsresult debug_rv; |
michael@0 | 113 | nsCOMPtr<nsIURI> debugClone; |
michael@0 | 114 | debug_rv = aURI->Clone(getter_AddRefs(debugClone)); |
michael@0 | 115 | if (NS_SUCCEEDED(debug_rv)) { |
michael@0 | 116 | nsCOMPtr<nsIURL> debugURL (do_QueryInterface(debugClone)); |
michael@0 | 117 | debug_rv = nsChromeRegistry::Canonify(debugURL); |
michael@0 | 118 | if (NS_SUCCEEDED(debug_rv)) { |
michael@0 | 119 | bool same; |
michael@0 | 120 | debug_rv = aURI->Equals(debugURL, &same); |
michael@0 | 121 | if (NS_SUCCEEDED(debug_rv)) { |
michael@0 | 122 | NS_ASSERTION(same, "Non-canonified chrome uri passed to nsChromeProtocolHandler::NewChannel!"); |
michael@0 | 123 | } |
michael@0 | 124 | } |
michael@0 | 125 | } |
michael@0 | 126 | #endif |
michael@0 | 127 | |
michael@0 | 128 | nsCOMPtr<nsIChannel> result; |
michael@0 | 129 | |
michael@0 | 130 | if (!nsChromeRegistry::gChromeRegistry) { |
michael@0 | 131 | // We don't actually want this ref, we just want the service to |
michael@0 | 132 | // initialize if it hasn't already. |
michael@0 | 133 | nsCOMPtr<nsIChromeRegistry> reg = |
michael@0 | 134 | mozilla::services::GetChromeRegistryService(); |
michael@0 | 135 | NS_ENSURE_TRUE(nsChromeRegistry::gChromeRegistry, NS_ERROR_FAILURE); |
michael@0 | 136 | } |
michael@0 | 137 | |
michael@0 | 138 | nsCOMPtr<nsIURI> resolvedURI; |
michael@0 | 139 | rv = nsChromeRegistry::gChromeRegistry->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); |
michael@0 | 140 | if (NS_FAILED(rv)) { |
michael@0 | 141 | #ifdef DEBUG |
michael@0 | 142 | nsAutoCString spec; |
michael@0 | 143 | aURI->GetSpec(spec); |
michael@0 | 144 | printf("Couldn't convert chrome URL: %s\n", spec.get()); |
michael@0 | 145 | #endif |
michael@0 | 146 | return rv; |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); |
michael@0 | 150 | NS_ENSURE_SUCCESS(rv, rv); |
michael@0 | 151 | |
michael@0 | 152 | rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); |
michael@0 | 153 | if (NS_FAILED(rv)) return rv; |
michael@0 | 154 | |
michael@0 | 155 | #ifdef DEBUG |
michael@0 | 156 | nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(result)); |
michael@0 | 157 | if (fileChan) { |
michael@0 | 158 | nsCOMPtr<nsIFile> file; |
michael@0 | 159 | fileChan->GetFile(getter_AddRefs(file)); |
michael@0 | 160 | |
michael@0 | 161 | bool exists = false; |
michael@0 | 162 | file->Exists(&exists); |
michael@0 | 163 | if (!exists) { |
michael@0 | 164 | nsAutoCString path; |
michael@0 | 165 | file->GetNativePath(path); |
michael@0 | 166 | printf("Chrome file doesn't exist: %s\n", path.get()); |
michael@0 | 167 | } |
michael@0 | 168 | } |
michael@0 | 169 | #endif |
michael@0 | 170 | |
michael@0 | 171 | // Make sure that the channel remembers where it was |
michael@0 | 172 | // originally loaded from. |
michael@0 | 173 | nsLoadFlags loadFlags = 0; |
michael@0 | 174 | result->GetLoadFlags(&loadFlags); |
michael@0 | 175 | result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE); |
michael@0 | 176 | rv = result->SetOriginalURI(aURI); |
michael@0 | 177 | if (NS_FAILED(rv)) return rv; |
michael@0 | 178 | |
michael@0 | 179 | // Get a system principal for content files and set the owner |
michael@0 | 180 | // property of the result |
michael@0 | 181 | nsCOMPtr<nsIURL> url = do_QueryInterface(aURI); |
michael@0 | 182 | nsAutoCString path; |
michael@0 | 183 | rv = url->GetPath(path); |
michael@0 | 184 | if (StringBeginsWith(path, NS_LITERAL_CSTRING("/content/"))) |
michael@0 | 185 | { |
michael@0 | 186 | nsCOMPtr<nsIScriptSecurityManager> securityManager = |
michael@0 | 187 | do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); |
michael@0 | 188 | if (NS_FAILED(rv)) return rv; |
michael@0 | 189 | |
michael@0 | 190 | nsCOMPtr<nsIPrincipal> principal; |
michael@0 | 191 | rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal)); |
michael@0 | 192 | if (NS_FAILED(rv)) return rv; |
michael@0 | 193 | |
michael@0 | 194 | nsCOMPtr<nsISupports> owner = do_QueryInterface(principal); |
michael@0 | 195 | result->SetOwner(owner); |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | // XXX Removed dependency-tracking code from here, because we're not |
michael@0 | 199 | // tracking them anyways (with fastload we checked only in DEBUG |
michael@0 | 200 | // and with startupcache not at all), but this is where we would start |
michael@0 | 201 | // if we need to re-add. |
michael@0 | 202 | // See bug 531886, bug 533038. |
michael@0 | 203 | result->SetContentCharset(NS_LITERAL_CSTRING("UTF-8")); |
michael@0 | 204 | |
michael@0 | 205 | *aResult = result; |
michael@0 | 206 | NS_ADDREF(*aResult); |
michael@0 | 207 | return NS_OK; |
michael@0 | 208 | } |
michael@0 | 209 | |
michael@0 | 210 | //////////////////////////////////////////////////////////////////////////////// |