content/base/src/ThirdPartyUtil.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "ThirdPartyUtil.h"
     6 #include "mozilla/Preferences.h"
     7 #include "nsNetUtil.h"
     8 #include "nsIServiceManager.h"
     9 #include "nsIHttpChannelInternal.h"
    10 #include "nsIDOMWindow.h"
    11 #include "nsICookiePermission.h"
    12 #include "nsIDOMDocument.h"
    13 #include "nsIDocument.h"
    14 #include "nsILoadContext.h"
    15 #include "nsIPrincipal.h"
    16 #include "nsIScriptObjectPrincipal.h"
    17 #include "nsThreadUtils.h"
    18 #include "nsPrintfCString.h"
    19 #include "nsIConsoleService.h"
    20 #include "nsContentUtils.h"
    22 NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil)
    24 nsresult
    25 ThirdPartyUtil::Init()
    26 {
    27   NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_AVAILABLE);
    29   nsresult rv;
    30   mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
    31   mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
    32   return rv;
    33 }
    35 // Determine if aFirstDomain is a different base domain to aSecondURI; or, if
    36 // the concept of base domain does not apply, determine if the two hosts are not
    37 // string-identical.
    38 nsresult
    39 ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain,
    40                                      nsIURI* aSecondURI,
    41                                      bool* aResult)
    42 {
    43   NS_ASSERTION(aSecondURI, "null URI!");
    45   // Get the base domain for aSecondURI.
    46   nsCString secondDomain;
    47   nsresult rv = GetBaseDomain(aSecondURI, secondDomain);
    48   if (NS_FAILED(rv))
    49     return rv;
    51   // Check strict equality.
    52   *aResult = aFirstDomain != secondDomain;
    53   return NS_OK;
    54 }
    56 // Return true if aURI's scheme is white listed, in which case
    57 // getFirstPartyURI() will not require that the firstPartyURI contains a host.
    58 bool ThirdPartyUtil::SchemeIsWhiteListed(nsIURI *aURI)
    59 {
    60   if (!aURI)
    61     return false;
    63   nsAutoCString scheme;
    64   nsresult rv = aURI->GetScheme(scheme);
    65   NS_ENSURE_SUCCESS(rv, false);
    67   return (scheme.Equals("about") || scheme.Equals("moz-safe-about")
    68           || scheme.Equals("chrome"));
    69 }
    71 // Get the URI associated with a window.
    72 already_AddRefed<nsIURI>
    73 ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin)
    74 {
    75   nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(aWin);
    76   NS_ENSURE_TRUE(scriptObjPrin, nullptr);
    78   nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
    79   NS_ENSURE_TRUE(prin, nullptr);
    81   nsCOMPtr<nsIURI> result;
    82   prin->GetURI(getter_AddRefs(result));
    83   return result.forget();
    84 }
    87 nsresult
    88 ThirdPartyUtil::GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI)
    89 {
    90   /* to find the originating URI, we use the loadgroup of the channel to obtain
    91    * the window owning the load, and from there, we find the top same-type
    92    * window and its URI. there are several possible cases:
    93    *
    94    * 1) no channel.
    95    *
    96    * 2) a channel with the "force allow third party cookies" option set.
    97    *    since we may not have a window, we return the channel URI in this case.
    98    *
    99    * 3) a channel, but no window. this can occur when the consumer kicking
   100    *    off the load doesn't provide one to the channel, and should be limited
   101    *    to loads of certain types of resources.
   102    *
   103    * 4) a window equal to the top window of same type, with the channel its
   104    *    document channel. this covers the case of a freshly kicked-off load
   105    *    (e.g. the user typing something in the location bar, or clicking on a
   106    *    bookmark), where the window's URI hasn't yet been set, and will be
   107    *    bogus. we return the channel URI in this case.
   108    *
   109    * 5) Anything else. this covers most cases for an ordinary page load from
   110    *    the location bar, and will catch nested frames within a page, image
   111    *    loads, etc. we return the URI of the root window's document's principal
   112    *    in this case.
   113    */
   115   *aURI = nullptr;
   117   // case 1)
   118   if (!aChannel)
   119     return NS_ERROR_NULL_POINTER;
   121   // case 2)
   122   nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel);
   123   if (httpChannelInternal)
   124   {
   125     bool doForce = false;
   126     if (NS_SUCCEEDED(httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce)) && doForce)
   127     {
   128       // return the channel's URI (we may not have a window)
   129       aChannel->GetURI(aURI);
   130       if (!*aURI)
   131         return NS_ERROR_NULL_POINTER;
   133       return NS_OK;
   134     }
   136     // TODO: Why don't we just use this here:
   137     // httpChannelInternal->GetDocumentURI(aURI);
   138   }
   140   // find the associated window and its top window
   141   nsCOMPtr<nsILoadContext> ctx;
   142   NS_QueryNotificationCallbacks(aChannel, ctx);
   143   nsCOMPtr<nsIDOMWindow> topWin, ourWin;
   144   if (ctx) {
   145     ctx->GetTopWindow(getter_AddRefs(topWin));
   146     ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
   147   }
   149   // case 3)
   150   if (!topWin)
   151     return NS_ERROR_INVALID_ARG;
   153   // case 4)
   154   if (ourWin == topWin) {
   155     // Check whether this is the document channel for this window (representing
   156     // a load of a new page).  This is a bit of a nasty hack, but we will
   157     // hopefully flag these channels better later.
   158     nsLoadFlags flags;
   159     aChannel->GetLoadFlags(&flags);
   161     if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
   162       // get the channel URI - the window's will be bogus
   163       aChannel->GetURI(aURI);
   164       if (!*aURI)
   165         return NS_ERROR_NULL_POINTER;
   167       return NS_OK;
   168     }
   169   }
   171   // case 5) - get the originating URI from the top window's principal
   172   nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin);
   173   NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED);
   175   nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
   176   NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
   178   prin->GetURI(aURI);
   180   if (!*aURI)
   181     return NS_ERROR_NULL_POINTER;
   183   // all done!
   184   return NS_OK;
   185 }
   188 // Determine if aFirstURI is third party with respect to aSecondURI. See docs
   189 // for mozIThirdPartyUtil.
   190 NS_IMETHODIMP
   191 ThirdPartyUtil::IsThirdPartyURI(nsIURI* aFirstURI,
   192                                 nsIURI* aSecondURI,
   193                                 bool* aResult)
   194 {
   195   NS_ENSURE_ARG(aFirstURI);
   196   NS_ENSURE_ARG(aSecondURI);
   197   NS_ASSERTION(aResult, "null outparam pointer");
   199   nsCString firstHost;
   200   nsresult rv = GetBaseDomain(aFirstURI, firstHost);
   201   if (NS_FAILED(rv))
   202     return rv;
   204   return IsThirdPartyInternal(firstHost, aSecondURI, aResult);
   205 }
   207 // Determine if any URI of the window hierarchy of aWindow is foreign with
   208 // respect to aSecondURI. See docs for mozIThirdPartyUtil.
   209 NS_IMETHODIMP
   210 ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
   211                                    nsIURI* aURI,
   212                                    bool* aResult)
   213 {
   214   NS_ENSURE_ARG(aWindow);
   215   NS_ASSERTION(aResult, "null outparam pointer");
   217   bool result;
   219   // Get the URI of the window, and its base domain.
   220   nsCOMPtr<nsIURI> currentURI = GetURIFromWindow(aWindow);
   221   NS_ENSURE_TRUE(currentURI, NS_ERROR_INVALID_ARG);
   223   nsCString bottomDomain;
   224   nsresult rv = GetBaseDomain(currentURI, bottomDomain);
   225   if (NS_FAILED(rv))
   226     return rv;
   228   if (aURI) {
   229     // Determine whether aURI is foreign with respect to currentURI.
   230     rv = IsThirdPartyInternal(bottomDomain, aURI, &result);
   231     if (NS_FAILED(rv))
   232       return rv;
   234     if (result) {
   235       *aResult = true;
   236       return NS_OK;
   237     }
   238   }
   240   nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
   241   nsCOMPtr<nsIURI> parentURI;
   242   do {
   243     // We use GetScriptableParent rather than GetParent because we consider
   244     // <iframe mozbrowser/mozapp> to be a top-level frame.
   245     rv = current->GetScriptableParent(getter_AddRefs(parent));
   246     NS_ENSURE_SUCCESS(rv, rv);
   248     if (SameCOMIdentity(parent, current)) {
   249       // We're at the topmost content window. We already know the answer.
   250       *aResult = false;
   251       return NS_OK;
   252     }
   254     parentURI = GetURIFromWindow(parent);
   255     NS_ENSURE_TRUE(parentURI, NS_ERROR_INVALID_ARG);
   257     rv = IsThirdPartyInternal(bottomDomain, parentURI, &result);
   258     if (NS_FAILED(rv))
   259       return rv;
   261     if (result) {
   262       *aResult = true;
   263       return NS_OK;
   264     }
   266     current = parent;
   267     currentURI = parentURI;
   268   } while (1);
   270   NS_NOTREACHED("should've returned");
   271   return NS_ERROR_UNEXPECTED;
   272 }
   274 // Determine if the URI associated with aChannel or any URI of the window
   275 // hierarchy associated with the channel is foreign with respect to aSecondURI.
   276 // See docs for mozIThirdPartyUtil.
   277 NS_IMETHODIMP 
   278 ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
   279                                     nsIURI* aURI,
   280                                     bool* aResult)
   281 {
   282   NS_ENSURE_ARG(aChannel);
   283   NS_ASSERTION(aResult, "null outparam pointer");
   285   nsresult rv;
   286   bool doForce = false;
   287   nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
   288     do_QueryInterface(aChannel);
   289   if (httpChannelInternal) {
   290     rv = httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce);
   291     NS_ENSURE_SUCCESS(rv, rv);
   293     // If aURI was not supplied, and we're forcing, then we're by definition
   294     // not foreign. If aURI was supplied, we still want to check whether it's
   295     // foreign with respect to the channel URI. (The forcing only applies to
   296     // whatever window hierarchy exists above the channel.)
   297     if (doForce && !aURI) {
   298       *aResult = false;
   299       return NS_OK;
   300     }
   301   }
   303   // Obtain the URI from the channel, and its base domain.
   304   nsCOMPtr<nsIURI> channelURI;
   305   aChannel->GetURI(getter_AddRefs(channelURI));
   306   NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);
   308   nsCString channelDomain;
   309   rv = GetBaseDomain(channelURI, channelDomain);
   310   if (NS_FAILED(rv))
   311     return rv;
   313   if (aURI) {
   314     // Determine whether aURI is foreign with respect to channelURI.
   315     bool result;
   316     rv = IsThirdPartyInternal(channelDomain, aURI, &result);
   317     if (NS_FAILED(rv))
   318      return rv;
   320     // If it's foreign, or we're forcing, we're done.
   321     if (result || doForce) {
   322       *aResult = result;
   323       return NS_OK;
   324     }
   325   }
   327   // Find the associated window and its parent window.
   328   nsCOMPtr<nsILoadContext> ctx;
   329   NS_QueryNotificationCallbacks(aChannel, ctx);
   330   if (!ctx) return NS_ERROR_INVALID_ARG;
   332   // If there is no window, the consumer kicking off the load didn't provide one
   333   // to the channel. This is limited to loads of certain types of resources. If
   334   // those loads require cookies, the forceAllowThirdPartyCookie property should
   335   // be set on the channel.
   336   nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
   337   ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
   338   if (!ourWin) return NS_ERROR_INVALID_ARG;
   340   // We use GetScriptableParent rather than GetParent because we consider
   341   // <iframe mozbrowser/mozapp> to be a top-level frame.
   342   ourWin->GetScriptableParent(getter_AddRefs(parentWin));
   343   NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
   345   // Check whether this is the document channel for this window (representing a
   346   // load of a new page). In that situation we want to avoid comparing
   347   // channelURI to ourWin, since what's in ourWin right now will be replaced as
   348   // the channel loads.  This covers the case of a freshly kicked-off load
   349   // (e.g. the user typing something in the location bar, or clicking on a
   350   // bookmark), where the window's URI hasn't yet been set, and will be bogus.
   351   // It also covers situations where a subframe is navigated to someting that
   352   // is same-origin with all its ancestors.  This is a bit of a nasty hack, but
   353   // we will hopefully flag these channels better later.
   354   nsLoadFlags flags;
   355   rv = aChannel->GetLoadFlags(&flags);
   356   NS_ENSURE_SUCCESS(rv, rv);
   358   if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
   359     if (SameCOMIdentity(ourWin, parentWin)) {
   360       // We only need to compare aURI to the channel URI -- the window's will be
   361       // bogus. We already know the answer.
   362       *aResult = false;
   363       return NS_OK;
   364     }
   366     // Make sure to still compare to ourWin's ancestors
   367     ourWin = parentWin;
   368   }
   370   // Check the window hierarchy. This covers most cases for an ordinary page
   371   // load from the location bar.
   372   return IsThirdPartyWindow(ourWin, channelURI, aResult);
   373 }
   375 // Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
   376 // "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
   377 // dot may be present. If aHostURI is an IP address, an alias such as
   378 // 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will
   379 // be the exact host. The result of this function should only be used in exact
   380 // string comparisons, since substring comparisons will not be valid for the
   381 // special cases elided above.
   382 NS_IMETHODIMP
   383 ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
   384                               nsACString& aBaseDomain)
   385 {
   386   // Get the base domain. this will fail if the host contains a leading dot,
   387   // more than one trailing dot, or is otherwise malformed.
   388   nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
   389   if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
   390       rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
   391     // aHostURI is either an IP address, an alias such as 'localhost', an eTLD
   392     // such as 'co.uk', or the empty string. Uses the normalized host in such
   393     // cases.
   394     rv = aHostURI->GetAsciiHost(aBaseDomain);
   395   }
   396   NS_ENSURE_SUCCESS(rv, rv);
   398   // aHostURI (and thus aBaseDomain) may be the string '.'. If so, fail.
   399   if (aBaseDomain.Length() == 1 && aBaseDomain.Last() == '.')
   400     return NS_ERROR_INVALID_ARG;
   402   // Reject any URIs without a host that aren't file:// URIs. This makes it the
   403   // only way we can get a base domain consisting of the empty string, which
   404   // means we can safely perform foreign tests on such URIs where "not foreign"
   405   // means "the involved URIs are all file://".
   406   if (aBaseDomain.IsEmpty()) {
   407     bool isFileURI = false;
   408     aHostURI->SchemeIs("file", &isFileURI);
   409     NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG);
   410   }
   412   return NS_OK;
   413 }
   415 // Returns true if First Party Isolation is currently active for the given nsIChannel.
   416 // Depends on Preference setting and possibly the state of Private Browsing mode.
   417 bool ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc)
   418 {
   419   int32_t isolationState = mozilla::Preferences::GetInt("privacy.thirdparty.isolate");
   420   if (isolationState == 1) {
   421     if (!aChannel && aDoc) {
   422       // No channel passed directly. Can we get a channel from aDoc?
   423       aChannel = aDoc->GetChannel();
   424     }
   425     return aChannel && NS_UsePrivateBrowsing(aChannel);
   426   } else { // (isolationState == 0) || (isolationState == 2)
   427     return (isolationState == 2);
   428   }
   429 }
   431 // Produces a URI that uniquely identifies the first party to which
   432 // image cache and dom storage objects should be isolated. If isolation
   433 // is deactivated, then aOutput will return null.
   434 // Not scriptable due to the use of an nsIDocument parameter.
   435 NS_IMETHODIMP
   436 ThirdPartyUtil::GetFirstPartyIsolationURI(nsIChannel *aChannel, nsIDocument *aDoc, nsIURI **aOutput)
   437 {
   438   bool isolationActive = IsFirstPartyIsolationActive(aChannel, aDoc);
   439   if (isolationActive) {
   440     return GetFirstPartyURI(aChannel, aDoc, aOutput);
   441   } else {
   442     // We return a null pointer when isolation is off.
   443     *aOutput = nullptr;
   444     return NS_OK;
   445   }
   446 }
   448 // Not scriptable due to the use of an nsIDocument parameter.
   449 NS_IMETHODIMP
   450 ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel,
   451                                  nsIDocument *aDoc,
   452                                  nsIURI **aOutput)
   453 {
   454   return GetFirstPartyURIInternal(aChannel, aDoc, true, aOutput);
   455 }
   457 nsresult
   458 ThirdPartyUtil::GetFirstPartyURIInternal(nsIChannel *aChannel,
   459                                          nsIDocument *aDoc,
   460                                          bool aLogErrors,
   461                                          nsIURI **aOutput)
   462 {
   463   nsresult rv = NS_ERROR_NULL_POINTER;
   464   nsCOMPtr<nsIURI> srcURI;
   466   if (!aOutput)
   467     return rv;
   469   *aOutput = nullptr;
   471   if (!aChannel && aDoc) {
   472     aChannel = aDoc->GetChannel();
   473   }
   475   // If aChannel is specified or available, use the official route
   476   // for sure
   477   if (aChannel) {
   478     rv = GetOriginatingURI(aChannel, aOutput);
   479     aChannel->GetURI(getter_AddRefs(srcURI));
   480     if (NS_SUCCEEDED(rv) && *aOutput) {
   481       // At this point, about: and chrome: URLs have been mapped to file: or
   482       // jar: URLs.  Try to recover the original URL.
   483       nsAutoCString scheme;
   484       nsresult rv2 = (*aOutput)->GetScheme(scheme);
   485       NS_ENSURE_SUCCESS(rv2, rv2);
   486       if (scheme.Equals("file") || scheme.Equals("jar")) {
   487         nsCOMPtr<nsIURI> originalURI;
   488         rv2 = aChannel->GetOriginalURI(getter_AddRefs(originalURI));
   489         if (NS_SUCCEEDED(rv2) && originalURI) {
   490           NS_RELEASE(*aOutput);
   491           NS_ADDREF(*aOutput = originalURI);
   492         }
   493       }
   494     }
   495   }
   497   // If the channel was missing, closed or broken, try the
   498   // window hierarchy directly.
   499   //
   500   // This might fail to work for first-party loads themselves, but
   501   // we don't need this codepath for that case.
   502   if (NS_FAILED(rv) && aDoc) {
   503     nsCOMPtr<nsIDOMWindow> top;
   504     nsCOMPtr<nsIDOMDocument> topDDoc;
   505     nsIURI *docURI = nullptr;
   506     srcURI = aDoc->GetDocumentURI();
   508     if (aDoc->GetWindow()) {
   509       aDoc->GetWindow()->GetTop(getter_AddRefs(top));
   510       top->GetDocument(getter_AddRefs(topDDoc));
   512       nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc));
   513       docURI = topDoc->GetOriginalURI();
   514       if (docURI) {
   515         // Give us a mutable URI and also addref
   516         rv = NS_EnsureSafeToReturn(docURI, aOutput);
   517       }
   518     } else {
   519       // XXX: Chrome callers (such as NoScript) can end up here
   520       // through getImageData/canvas usage with no document state
   521       // (no Window and a document URI of about:blank). Propogate
   522       // rv fail (by doing nothing), and hope caller recovers.
   523     }
   525     if (*aOutput)
   526       rv = NS_OK;
   527   }
   529   if (*aOutput && !SchemeIsWhiteListed(*aOutput)) {
   530     // If URI scheme is not whitelisted and the URI lacks a hostname, force a
   531     // failure.
   532     nsAutoCString host;
   533     rv = (*aOutput)->GetHost(host);
   534     if (NS_SUCCEEDED(rv) && (host.Length() == 0)) {
   535       rv = NS_ERROR_FAILURE;
   536     }
   537   }
   539   // Log failure to error console.
   540   if (aLogErrors && NS_FAILED(rv)) {
   541     nsCOMPtr<nsIConsoleService> console
   542                               (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
   543     if (console) {
   544       nsCString spec;
   545       nsCString srcSpec("unknown");
   547       if (srcURI)
   548         srcURI->GetSpec(srcSpec);
   550       if (*aOutput)
   551         (*aOutput)->GetSpec(spec);
   552       if (spec.Length() > 0) {
   553         nsPrintfCString msg("getFirstPartyURI failed for %s: no host in first party URI %s",
   554                             srcSpec.get(), spec.get()); // TODO: L10N
   555         console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get());
   556       } else {
   557         nsPrintfCString msg("getFirstPartyURI failed for %s: 0x%x", srcSpec.get(), rv);
   558         console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get());
   559       }
   560     }
   562     if (*aOutput) {
   563       // discard return object.
   564       (*aOutput)->Release();
   565       *aOutput = nullptr;
   566     }
   567   }
   569   // TODO: We could provide a route through the loadgroup + notification
   570   // callbacks too, but either channel or document was always available
   571   // in the cases where this function was originally needed (the image cache).
   572   // The notification callbacks also appear to suffers from the same limitation
   573   // as the document path. See nsICookiePermissions.GetOriginatingURI() for
   574   // details.
   576   return rv;
   577 }
   579 NS_IMETHODIMP
   580 ThirdPartyUtil::GetFirstPartyURIFromChannel(nsIChannel *aChannel,
   581                                             bool aLogErrors,
   582                                             nsIURI **aOutput)
   583 {
   584   return GetFirstPartyURIInternal(aChannel, nullptr, aLogErrors, aOutput);
   585 }
   587 NS_IMETHODIMP
   588 ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI,
   589                                               nsACString& aHost)
   590 {
   591   if (!aFirstPartyURI)
   592     return NS_ERROR_INVALID_ARG;
   594   if (!SchemeIsWhiteListed(aFirstPartyURI)) {
   595     nsresult rv = aFirstPartyURI->GetHost(aHost);
   596     return (aHost.Length() > 0) ? NS_OK : rv;
   597   }
   599   // This URI lacks a host, so construct and return a pseudo-host.
   600   aHost = "--NoFirstPartyHost-";
   602   // Append the scheme.  To ensure that the pseudo-hosts are consistent
   603   // when the hacky "moz-safe-about" scheme is used, map it back to "about".
   604   nsAutoCString scheme;
   605   nsresult rv = aFirstPartyURI->GetScheme(scheme);
   606   NS_ENSURE_SUCCESS(rv, rv);
   607   if (scheme.Equals("moz-safe-about"))
   608     aHost.Append("about");
   609   else
   610     aHost.Append(scheme);
   612   // Append the URL's file name (e.g., -browser.xul) or its path (e.g.,
   613   // -home for about:home)
   614   nsAutoCString s;
   615   nsCOMPtr<nsIURL> url = do_QueryInterface(aFirstPartyURI);
   616   if (url)
   617     url->GetFileName(s);
   618   else
   619     aFirstPartyURI->GetPath(s);
   621   if (s.Length() > 0) {
   622     aHost.Append("-");
   623     aHost.Append(s);
   624   }
   626   aHost.Append("--");
   627   return NS_OK;
   628 }

mercurial