Bug 1476928 - Remove nsIURI.CloneIgnoringRef and nsIURI.CloneWithNewRef r=JuniorHsu
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 23 Jul 2018 11:28:47 +0000
changeset 427758 5288e1d49e718b48fe60947228523c1a83d58e30
parent 427757 f19f8d717c6bb7497b6242a860fd96d8d82c50b7
child 427759 1bb77a767731a18e4c63de6d69e2997fb3c1b577
push id34315
push usercsabou@mozilla.com
push dateMon, 23 Jul 2018 15:48:07 +0000
treeherdermozilla-central@f5959a93f562 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJuniorHsu
bugs1476928
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1476928 - Remove nsIURI.CloneIgnoringRef and nsIURI.CloneWithNewRef r=JuniorHsu The patch introduces NS_GetURIWithNewRef and NS_GetURIWithNewRef which perform the same function. Differential Revision: https://phabricator.services.mozilla.com/D2239
caps/NullPrincipalURI.cpp
dom/base/Location.cpp
dom/base/Location.h
dom/base/nsContentSink.cpp
dom/base/nsDocument.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/fetch/FetchDriver.cpp
dom/fetch/Request.cpp
dom/security/nsCSPContext.cpp
dom/serviceworkers/ServiceWorkerContainer.cpp
dom/serviceworkers/ServiceWorkerPrivate.cpp
dom/xbl/nsXBLService.cpp
dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
dom/xul/nsXULPrototypeCache.cpp
image/decoders/icon/nsIconURI.cpp
modules/libjar/nsJARURI.cpp
netwerk/base/nsIOService.cpp
netwerk/base/nsIURI.idl
netwerk/base/nsNetUtil.cpp
netwerk/base/nsNetUtil.h
netwerk/base/nsSimpleNestedURI.cpp
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsStandardURL.cpp
netwerk/cache/nsDiskCacheDeviceSQL.cpp
netwerk/cache2/AppCacheStorage.cpp
netwerk/cache2/CacheStorage.cpp
netwerk/cache2/OldWrappers.cpp
netwerk/protocol/about/nsAboutProtocolHandler.cpp
netwerk/protocol/data/nsDataChannel.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/test/unit/test_URIs.js
netwerk/test/unit/test_URIs2.js
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/ExtensionPolicyService.cpp
toolkit/components/extensions/MatchPattern.cpp
uriloader/prefetch/nsOfflineCacheUpdate.cpp
--- a/caps/NullPrincipalURI.cpp
+++ b/caps/NullPrincipalURI.cpp
@@ -286,32 +286,16 @@ NullPrincipalURI::SetUserPass(const nsAC
 nsresult
 NullPrincipalURI::Clone(nsIURI** _newURI)
 {
   nsCOMPtr<nsIURI> uri = new NullPrincipalURI(*this);
   uri.forget(_newURI);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-NullPrincipalURI::CloneIgnoringRef(nsIURI** _newURI)
-{
-  // GetRef/SetRef not supported by NullPrincipalURI, so
-  // CloneIgnoringRef() is the same as Clone().
-  return Clone(_newURI);
-}
-
-NS_IMETHODIMP
-NullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI** _newURI)
-{
-  // GetRef/SetRef not supported by NullPrincipalURI, so
-  // CloneWithNewRef() is the same as Clone().
-  return Clone(_newURI);
-}
-
 NS_IMPL_ISUPPORTS(NullPrincipalURI::Mutator, nsIURISetters, nsIURIMutator)
 
 NS_IMETHODIMP
 NullPrincipalURI::Mutate(nsIURIMutator** aMutator)
 {
     RefPtr<NullPrincipalURI::Mutator> mutator = new NullPrincipalURI::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -202,36 +202,16 @@ Location::GetURI(nsIURI** aURI, bool aGe
 
   nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return urifixup->CreateExposableURI(uri, aURI);
 }
 
 nsresult
-Location::GetWritableURI(nsIURI** aURI, const nsACString* aNewRef)
-{
-  *aURI = nullptr;
-
-  nsCOMPtr<nsIURI> uri;
-
-  nsresult rv = GetURI(getter_AddRefs(uri));
-  if (NS_FAILED(rv) || !uri) {
-    return rv;
-  }
-
-  if (!aNewRef) {
-    uri.forget(aURI);
-    return NS_OK;
-  }
-
-  return uri->CloneWithNewRef(*aNewRef, aURI);
-}
-
-nsresult
 Location::SetURI(nsIURI* aURI, bool aReplace)
 {
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   if (docShell) {
     RefPtr<nsDocShellLoadInfo> loadInfo;
 
     if(NS_FAILED(CheckURL(aURI, getter_AddRefs(loadInfo))))
       return NS_ERROR_FAILURE;
@@ -308,17 +288,24 @@ Location::SetHash(const nsAString& aHash
   }
 
   NS_ConvertUTF16toUTF8 hash(aHash);
   if (hash.IsEmpty() || hash.First() != char16_t('#')) {
     hash.Insert(char16_t('#'), 0);
   }
 
   nsCOMPtr<nsIURI> uri;
-  aRv = GetWritableURI(getter_AddRefs(uri), &hash);
+  aRv = GetURI(getter_AddRefs(uri));
+  if (NS_WARN_IF(aRv.Failed()) || !uri) {
+    return;
+  }
+
+  aRv = NS_MutateURI(uri)
+          .SetRef(hash)
+          .Finalize(uri);
   if (NS_WARN_IF(aRv.Failed()) || !uri) {
     return;
   }
 
   aRv = SetURI(uri);
 }
 
 void
--- a/dom/base/Location.h
+++ b/dom/base/Location.h
@@ -161,21 +161,16 @@ protected:
   virtual ~Location();
 
   // In the case of jar: uris, we sometimes want the place the jar was
   // fetched from as the URI instead of the jar: uri itself.  Pass in
   // true for aGetInnermostURI when that's the case.
   // Note, this method can return NS_OK with a null value for aURL. This happens
   // if the docShell is null.
   nsresult GetURI(nsIURI** aURL, bool aGetInnermostURI = false);
-  // Note, this method can return NS_OK with a null value for aURL. This happens
-  // if the docShell is null.
-  nsresult GetWritableURI(nsIURI** aURL,
-                          // If not null, give it the new ref
-                          const nsACString* aNewRef = nullptr);
   nsresult SetURI(nsIURI* aURL, bool aReplace = false);
   nsresult SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
                            bool aReplace);
   nsresult SetHrefWithContext(JSContext* cx, const nsAString& aHref,
                               bool aReplace);
 
   nsresult GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL);
   nsresult CheckURL(nsIURI *url, nsDocShellLoadInfo** aLoadInfo);
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -371,17 +371,17 @@ nsContentSink::LinkContextIsOurDocument(
   }
 
   nsIURI* docUri = mDocument->GetDocumentURI();
 
   // the document URI might contain a fragment identifier ("#...')
   // we want to ignore that because it's invisible to the server
   // and just affects the local interpretation in the recipient
   nsCOMPtr<nsIURI> contextUri;
-  nsresult rv = docUri->CloneIgnoringRef(getter_AddRefs(contextUri));
+  nsresult rv = NS_GetURIWithoutRef(docUri, getter_AddRefs(contextUri));
 
   if (NS_FAILED(rv)) {
     // copying failed
     return false;
   }
 
   // resolve anchor against context
   nsCOMPtr<nsIURI> resolvedUri;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -822,17 +822,17 @@ nsExternalResourceMap::RequestResource(n
   MOZ_ASSERT(aRequestingNode, "Must have a node");
   *aPendingLoad = nullptr;
   if (mHaveShutDown) {
     return nullptr;
   }
 
   // First, make sure we strip the ref from aURI.
   nsCOMPtr<nsIURI> clone;
-  nsresult rv = aURI->CloneIgnoringRef(getter_AddRefs(clone));
+  nsresult rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(clone));
   if (NS_FAILED(rv) || !clone) {
     return nullptr;
   }
 
   ExternalResource* resource;
   mMap.Get(clone, &resource);
   if (resource) {
     return resource->mDocument;
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1278,17 +1278,17 @@ nsGlobalWindowOuter::WouldReuseInnerWind
 
   if (!mDoc->IsInitialDocument()) {
     return false;
   }
 
 #ifdef DEBUG
 {
   nsCOMPtr<nsIURI> uri;
-  mDoc->GetDocumentURI()->CloneIgnoringRef(getter_AddRefs(uri));
+  NS_GetURIWithoutRef(mDoc->GetDocumentURI(), getter_AddRefs(uri));
   NS_ASSERTION(NS_IsAboutBlank(uri), "How'd this happen?");
 }
 #endif
 
   // Great, we're the original document, check for one of the other
   // conditions.
 
   if (mDoc == aNewDocument) {
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -1282,17 +1282,17 @@ FetchDriver::AsyncOnChannelRedirect(nsIC
   // However, ignore internal redirects here.  We don't want to flip
   // Response.redirected to true if an internal redirect occurs.  These
   // should be transparent to script.
   if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
     nsCOMPtr<nsIURI> uri;
     MOZ_ALWAYS_SUCCEEDS(aNewChannel->GetURI(getter_AddRefs(uri)));
 
     nsCOMPtr<nsIURI> uriClone;
-    nsresult rv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
+    nsresult rv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriClone));
     if(NS_WARN_IF(NS_FAILED(rv))){
       return rv;
     }
     nsCString spec;
     rv = uriClone->GetSpec(spec);
     if(NS_WARN_IF(NS_FAILED(rv))){
       return rv;
     }
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -112,19 +112,17 @@ GetRequestURLFromDocument(nsIDocument* a
   nsAutoCString credentials;
   Unused << resolvedURI->GetUserPass(credentials);
   if (!credentials.IsEmpty()) {
     aRv.ThrowTypeError<MSG_URL_HAS_CREDENTIALS>(aInput);
     return;
   }
 
   nsCOMPtr<nsIURI> resolvedURIClone;
-  // We use CloneIgnoringRef to strip away the fragment even if the original URI
-  // is immutable.
-  aRv = resolvedURI->CloneIgnoringRef(getter_AddRefs(resolvedURIClone));
+  aRv = NS_GetURIWithoutRef(resolvedURI, getter_AddRefs(resolvedURIClone));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
   nsAutoCString spec;
   aRv = resolvedURIClone->GetSpec(spec);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
@@ -160,19 +158,17 @@ GetRequestURLFromChrome(const nsAString&
   nsAutoCString credentials;
   Unused << uri->GetUserPass(credentials);
   if (!credentials.IsEmpty()) {
     aRv.ThrowTypeError<MSG_URL_HAS_CREDENTIALS>(aInput);
     return;
   }
 
   nsCOMPtr<nsIURI> uriClone;
-  // We use CloneIgnoringRef to strip away the fragment even if the original URI
-  // is immutable.
-  aRv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
+  aRv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriClone));
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
   nsAutoCString spec;
   aRv = uriClone->GetSpec(spec);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -1513,17 +1513,17 @@ nsCSPContext::PermitsAncestry(nsIDocShel
       rv = NS_MutateURI(currentURI)
              .SetRef(EmptyCString())
              .SetUserPass(EmptyCString())
              .Finalize(uriClone);
 
       // If setUserPass fails for some reason, just return a clone of the
       // current URI
       if (NS_FAILED(rv)) {
-        rv = currentURI->CloneIgnoringRef(getter_AddRefs(uriClone));
+        rv = NS_GetURIWithoutRef(currentURI, getter_AddRefs(uriClone));
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       if (CSPCONTEXTLOGENABLED()) {
         CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, found ancestor: %s",
                        uriClone->GetSpecOrDefault().get()));
       }
       ancestorsArray.AppendElement(uriClone);
--- a/dom/serviceworkers/ServiceWorkerContainer.cpp
+++ b/dom/serviceworkers/ServiceWorkerContainer.cpp
@@ -249,23 +249,23 @@ ServiceWorkerContainer::Register(const n
       NS_ConvertUTF8toUTF16 wSpec(spec);
       aRv.ThrowTypeError<MSG_INVALID_SCOPE>(aOptions.mScope.Value(), wSpec);
       return nullptr;
     }
   }
 
   // Strip the any ref from both the script and scope URLs.
   nsCOMPtr<nsIURI> cloneWithoutRef;
-  aRv = scriptURI->CloneIgnoringRef(getter_AddRefs(cloneWithoutRef));
+  aRv = NS_GetURIWithoutRef(scriptURI, getter_AddRefs(cloneWithoutRef));
   if (aRv.Failed()) {
     return nullptr;
   }
   scriptURI = cloneWithoutRef.forget();
 
-  aRv = scopeURI->CloneIgnoringRef(getter_AddRefs(cloneWithoutRef));
+  aRv = NS_GetURIWithoutRef(scopeURI, getter_AddRefs(cloneWithoutRef));
   if (aRv.Failed()) {
     return nullptr;
   }
   scopeURI = cloneWithoutRef.forget();
 
   aRv = ServiceWorkerScopeAndScriptAreValid(clientInfo.ref(),
                                             scopeURI,
                                             scriptURI);
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -1363,17 +1363,17 @@ public:
     rv = mInterceptedChannel->GetSecureUpgradedChannelURI(getter_AddRefs(uri));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Normally we rely on the Request constructor to strip the fragment, but
     // when creating the FetchEvent we bypass the constructor.  So strip the
     // fragment manually here instead.  We can't do it later when we create
     // the Request because that code executes off the main thread.
     nsCOMPtr<nsIURI> uriNoFragment;
-    rv = uri->CloneIgnoringRef(getter_AddRefs(uriNoFragment));
+    rv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriNoFragment));
     NS_ENSURE_SUCCESS(rv, rv);
     rv = uriNoFragment->GetSpec(mSpec);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = uri->GetRef(mFragment);
     NS_ENSURE_SUCCESS(rv, rv);
 
     uint32_t loadFlags;
     rv = channel->GetLoadFlags(&loadFlags);
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -910,17 +910,17 @@ nsXBLService::LoadBindingDocumentInfo(ns
   if (aOriginPrincipal && !IsSystemOrChromeURLPrincipal(aOriginPrincipal)) {
     NS_ENSURE_TRUE(!aBoundDocument || aBoundDocument->AllowXULXBL(),
                    NS_ERROR_XBL_BLOCKED);
   }
 
   RefPtr<nsXBLDocumentInfo> info;
 
   nsCOMPtr<nsIURI> documentURI;
-  nsresult rv = aBindingURI->CloneIgnoringRef(getter_AddRefs(documentURI));
+  nsresult rv = NS_GetURIWithoutRef(aBindingURI, getter_AddRefs(documentURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsBindingManager *bindingManager = nullptr;
 
   // The first thing to check is the binding manager, which (if it exists)
   // should have a reference to the nsXBLDocumentInfo if this document
   // has ever loaded this binding before.
   if (aBoundDocument) {
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -683,17 +683,17 @@ TX_CompileStylesheet(nsINode* aNode, txM
     uri->GetSpec(spec);
     NS_ConvertUTF8toUTF16 baseURI(spec);
 
     nsIURI* docUri = doc->GetDocumentURI();
     NS_ENSURE_TRUE(docUri, NS_ERROR_FAILURE);
 
     // We need to remove the ref, a URI with a ref would mean that we have an
     // embedded stylesheet.
-    docUri->CloneIgnoringRef(getter_AddRefs(uri));
+    NS_GetURIWithoutRef(docUri, getter_AddRefs(uri));
     NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
 
     uri->GetSpec(spec);
     NS_ConvertUTF8toUTF16 stylesheetURI(spec);
 
     RefPtr<txSyncCompileObserver> obs =
         new txSyncCompileObserver(aProcessor);
     NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -138,17 +138,17 @@ nsXULPrototypeCache::Observe(nsISupports
 
 nsXULPrototypeDocument*
 nsXULPrototypeCache::GetPrototype(nsIURI* aURI)
 {
     if (!aURI)
         return nullptr;
 
     nsCOMPtr<nsIURI> uriWithoutRef;
-    aURI->CloneIgnoringRef(getter_AddRefs(uriWithoutRef));
+    NS_GetURIWithoutRef(aURI, getter_AddRefs(uriWithoutRef));
 
     nsXULPrototypeDocument* protoDoc = mPrototypeTable.GetWeak(uriWithoutRef);
     if (protoDoc)
         return protoDoc;
 
     nsresult rv = BeginCaching(aURI);
     if (NS_FAILED(rv))
         return nullptr;
@@ -178,17 +178,17 @@ nsXULPrototypeCache::GetPrototype(nsIURI
 nsresult
 nsXULPrototypeCache::PutPrototype(nsXULPrototypeDocument* aDocument)
 {
     if (!aDocument->GetURI()) {
         return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIURI> uri;
-    aDocument->GetURI()->CloneIgnoringRef(getter_AddRefs(uri));
+    NS_GetURIWithoutRef(aDocument->GetURI(), getter_AddRefs(uri));
 
     // Put() releases any old value and addrefs the new one
     mPrototypeTable.Put(uri, aDocument);
 
     return NS_OK;
 }
 
 mozilla::StyleSheet*
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -530,33 +530,16 @@ nsMozIconURI::Clone(nsIURI** result)
   uri->mIconSize = mIconSize;
   uri->mIconState = mIconState;
   uri.forget(result);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsMozIconURI::CloneIgnoringRef(nsIURI** result)
-{
-  // GetRef/SetRef not supported by nsMozIconURI, so
-  // CloneIgnoringRef() is the same as Clone().
-  return Clone(result);
-}
-
-NS_IMETHODIMP
-nsMozIconURI::CloneWithNewRef(const nsACString& newRef, nsIURI** result)
-{
-  // GetRef/SetRef not supported by nsMozIconURI, so
-  // CloneWithNewRef() is the same as Clone().
-  return Clone(result);
-}
-
-
-NS_IMETHODIMP
 nsMozIconURI::Resolve(const nsACString& relativePath, nsACString& result)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetAsciiSpec(nsACString& aSpecA)
 {
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -599,43 +599,16 @@ nsJARURI::Clone(nsIURI **result)
     rv = CloneWithJARFileInternal(mJARFile, eHonorRef, getter_AddRefs(uri));
     if (NS_FAILED(rv)) return rv;
 
     uri.forget(result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJARURI::CloneIgnoringRef(nsIURI **result)
-{
-    nsresult rv;
-
-    nsCOMPtr<nsIJARURI> uri;
-    rv = CloneWithJARFileInternal(mJARFile, eIgnoreRef, getter_AddRefs(uri));
-    if (NS_FAILED(rv)) return rv;
-
-    uri.forget(result);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsJARURI::CloneWithNewRef(const nsACString& newRef, nsIURI **result)
-{
-    nsresult rv;
-
-    nsCOMPtr<nsIJARURI> uri;
-    rv = CloneWithJARFileInternal(mJARFile, eReplaceRef, newRef,
-                                  getter_AddRefs(uri));
-    if (NS_FAILED(rv)) return rv;
-
-    uri.forget(result);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsJARURI::Resolve(const nsACString &relativePath, nsACString &result)
 {
     nsresult rv;
 
     nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
     if (NS_FAILED(rv))
       return rv;
 
@@ -911,19 +884,19 @@ nsJARURI::CloneWithJARFileInternal(nsIUR
     }
 
     nsresult rv = NS_OK;
     nsCOMPtr<nsIURI> newJARFile = jarFile;
     nsCOMPtr<nsIURI> newJAREntryURI;
     if (refHandlingMode == eHonorRef) {
       newJAREntryURI = mJAREntry;
     } else if (refHandlingMode == eReplaceRef) {
-      rv = mJAREntry->CloneWithNewRef(newRef, getter_AddRefs(newJAREntryURI));
+      rv = NS_GetURIWithNewRef(mJAREntry, newRef, getter_AddRefs(newJAREntryURI));
     } else {
-      rv = mJAREntry->CloneIgnoringRef(getter_AddRefs(newJAREntryURI));
+      rv = NS_GetURIWithoutRef(mJAREntry, getter_AddRefs(newJAREntryURI));
     }
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<nsIURL> newJAREntry(do_QueryInterface(newJAREntryURI));
     NS_ASSERTION(newJAREntry, "This had better QI to nsIURL!");
 
     RefPtr<nsJARURI> uri = new nsJARURI();
     uri->mJARFile = newJARFile;
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -682,17 +682,17 @@ nsIOService::NewURI(const nsACString &aS
     if (NS_FAILED(rv)) {
         // then aSpec is relative
         if (!aBaseURI)
             return NS_ERROR_MALFORMED_URI;
 
         if (!aSpec.IsEmpty() && aSpec[0] == '#') {
             // Looks like a reference instead of a fully-specified URI.
             // --> initialize |uri| as a clone of |aBaseURI|, with ref appended.
-            return aBaseURI->CloneWithNewRef(aSpec, result);
+            return NS_GetURIWithNewRef(aBaseURI, aSpec, result);
         }
 
         rv = aBaseURI->GetScheme(scheme);
         if (NS_FAILED(rv)) return rv;
     }
 
     // now get the handler for this scheme
     nsCOMPtr<nsIProtocolHandler> handler;
--- a/netwerk/base/nsIURI.idl
+++ b/netwerk/base/nsIURI.idl
@@ -232,27 +232,16 @@ interface nsIURI : nsISupports
      * the value of the .ref member.
      *
      * eg. http://foo.com/# == http://foo.com/
      *     http://foo.com/#aaa == http://foo.com/#bbb
      */
     boolean equalsExceptRef(in nsIURI other);
 
     /**
-     * Clones the current URI, clearing the 'ref' attribute in the clone.
-     */
-    nsIURI cloneIgnoringRef();
-
-    /**
-     * Clones the current URI, replacing the 'ref' attribute in the clone with
-     * the ref supplied.
-     */
-    nsIURI cloneWithNewRef(in AUTF8String newRef);
-
-    /**
      * returns a string for the current URI with the ref element cleared.
      */
     readonly attribute AUTF8String specIgnoringRef;
 
     /**
      * Returns if there is a reference portion (the part after the "#") of the URI.
      */
     readonly attribute boolean hasRef;
--- a/netwerk/base/nsNetUtil.cpp
+++ b/netwerk/base/nsNetUtil.cpp
@@ -159,16 +159,57 @@ NS_NewFileURI(nsIURI **result,
     nsCOMPtr<nsIIOService> grip;
     rv = net_EnsureIOService(&ioService, grip);
     if (ioService)
         rv = ioService->NewFileURI(spec, result);
     return rv;
 }
 
 nsresult
+NS_GetURIWithNewRef(nsIURI* aInput,
+                    const nsACString& aRef,
+                    nsIURI** aOutput)
+{
+  if (NS_WARN_IF(!aInput || !aOutput)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  bool hasRef;
+  nsresult rv = aInput->GetHasRef(&hasRef);
+
+  nsAutoCString ref;
+  if (NS_SUCCEEDED(rv)) {
+    rv = aInput->GetRef(ref);
+  }
+
+  // If the ref is already equal to the new ref, we do not need to do anything.
+  // Also, if the GetRef failed (it could return NS_ERROR_NOT_IMPLEMENTED)
+  // we can assume SetRef would fail as well, so returning the original
+  // URI is OK.
+  if (NS_FAILED(rv) ||
+      (!hasRef && aRef.IsEmpty()) ||
+      (!aRef.IsEmpty() && aRef == ref)) {
+    nsCOMPtr<nsIURI> uri = aInput;
+    uri.forget(aOutput);
+    return NS_OK;
+  }
+
+  return NS_MutateURI(aInput)
+           .SetRef(aRef)
+           .Finalize(aOutput);
+}
+
+nsresult
+NS_GetURIWithoutRef(nsIURI* aInput,
+                    nsIURI** aOutput)
+{
+  return NS_GetURIWithNewRef(aInput, EmptyCString(), aOutput);
+}
+
+nsresult
 NS_NewChannelInternal(nsIChannel           **outChannel,
                       nsIURI                *aUri,
                       nsILoadInfo           *aLoadInfo,
                       PerformanceStorage    *aPerformanceStorage /* = nullptr */,
                       nsILoadGroup          *aLoadGroup /* = nullptr */,
                       nsIInterfaceRequestor *aCallbacks /* = nullptr */,
                       nsLoadFlags            aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
                       nsIIOService          *aIoService /* = nullptr */)
--- a/netwerk/base/nsNetUtil.h
+++ b/netwerk/base/nsNetUtil.h
@@ -98,16 +98,29 @@ nsresult NS_NewURI(nsIURI **result,
                   const char *spec,
                   nsIURI *baseURI = nullptr,
                   nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
 nsresult NS_NewFileURI(nsIURI **result,
                        nsIFile *spec,
                        nsIIOService *ioService = nullptr);     // pass in nsIIOService to optimize callers
 
+// These methods will only mutate the URI if the ref of aInput doesn't already
+// match the ref we are trying to set.
+// If aInput has no ref, and we are calling NS_GetURIWithoutRef, or
+// NS_GetURIWithNewRef with an empty string, then aOutput will be the same
+// as aInput. The same is true if aRef is already equal to the ref of aInput.
+// This is OK because URIs are immutable and threadsafe.
+// If the URI doesn't support ref fragments aOutput will be the same as aInput.
+nsresult NS_GetURIWithNewRef(nsIURI* aInput,
+                             const nsACString& aRef,
+                             nsIURI** aOutput);
+nsresult NS_GetURIWithoutRef(nsIURI* aInput,
+                             nsIURI** aOutput);
+
 nsresult NS_GetSanitizedURIStringFromURI(nsIURI *aUri,
                                          nsAString &aSanitizedSpec);
 
 /*
 * How to create a new Channel, using NS_NewChannel,
 * NS_NewChannelWithTriggeringPrincipal,
 * NS_NewInputStreamChannel, NS_NewChannelInternal
 * and it's variations:
--- a/netwerk/base/nsSimpleNestedURI.cpp
+++ b/netwerk/base/nsSimpleNestedURI.cpp
@@ -207,19 +207,19 @@ nsSimpleNestedURI::StartClone(nsSimpleUR
 {
     NS_ENSURE_TRUE(mInnerURI, nullptr);
 
     nsCOMPtr<nsIURI> innerClone;
     nsresult rv = NS_OK;
     if (refHandlingMode == eHonorRef) {
         innerClone = mInnerURI;
     } else if (refHandlingMode == eReplaceRef) {
-        rv = mInnerURI->CloneWithNewRef(newRef, getter_AddRefs(innerClone));
+        rv = NS_GetURIWithNewRef(mInnerURI, newRef, getter_AddRefs(innerClone));
     } else {
-        rv = mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+        rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone));
     }
 
     if (NS_FAILED(rv)) {
         return nullptr;
     }
 
     nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
     SetRefOnClone(url, refHandlingMode, newRef);
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -628,28 +628,16 @@ nsSimpleURI::SetRefOnClone(nsSimpleURI* 
 }
 
 nsresult
 nsSimpleURI::Clone(nsIURI** result)
 {
     return CloneInternal(eHonorRef, EmptyCString(), result);
 }
 
-NS_IMETHODIMP
-nsSimpleURI::CloneIgnoringRef(nsIURI** result)
-{
-    return CloneInternal(eIgnoreRef, EmptyCString(), result);
-}
-
-NS_IMETHODIMP
-nsSimpleURI::CloneWithNewRef(const nsACString &newRef, nsIURI** result)
-{
-    return CloneInternal(eReplaceRef, newRef, result);
-}
-
 nsresult
 nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
                            const nsACString &newRef,
                            nsIURI** result)
 {
     RefPtr<nsSimpleURI> url = StartClone(refHandlingMode, newRef);
     if (!url)
         return NS_ERROR_OUT_OF_MEMORY;
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -2274,29 +2274,16 @@ nsStandardURL::StartClone()
 }
 
 nsresult
 nsStandardURL::Clone(nsIURI **result)
 {
     return CloneInternal(eHonorRef, EmptyCString(), result);
 }
 
-
-NS_IMETHODIMP
-nsStandardURL::CloneIgnoringRef(nsIURI **result)
-{
-    return CloneInternal(eIgnoreRef, EmptyCString(), result);
-}
-
-NS_IMETHODIMP
-nsStandardURL::CloneWithNewRef(const nsACString& newRef, nsIURI **result)
-{
-    return CloneInternal(eReplaceRef, newRef, result);
-}
-
 nsresult
 nsStandardURL::CloneInternal(nsStandardURL::RefHandlingEnum refHandlingMode,
                              const nsACString& newRef,
                              nsIURI **result)
 
 {
     RefPtr<nsStandardURL> clone = StartClone();
     if (!clone)
--- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp
+++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp
@@ -747,17 +747,17 @@ nsApplicationCache::InitAsHandle(const n
 
 NS_IMETHODIMP
 nsApplicationCache::GetManifestURI(nsIURI **out)
 {
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), mGroup);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = uri->CloneIgnoringRef(out);
+  rv = NS_GetURIWithNewRef(uri, EmptyCString(), out);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsApplicationCache::GetGroupID(nsACString &out)
 {
@@ -1367,17 +1367,17 @@ GetGroupForCache(const nsACString& clien
 
 // static
 nsresult
 nsOfflineCacheDevice::BuildApplicationCacheGroupID(nsIURI *aManifestURL,
                                                    nsACString const &aOriginSuffix,
                                                    nsACString &_result)
 {
   nsCOMPtr<nsIURI> newURI;
-  nsresult rv = aManifestURL->CloneIgnoringRef(getter_AddRefs(newURI));
+  nsresult rv = NS_GetURIWithNewRef(aManifestURL, EmptyCString(), getter_AddRefs(newURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString manifestSpec;
   rv = newURI->GetAsciiSpec(manifestSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   _result.Assign(manifestSpec);
   _result.Append('#');
--- a/netwerk/cache2/AppCacheStorage.cpp
+++ b/netwerk/cache2/AppCacheStorage.cpp
@@ -10,16 +10,17 @@
 
 #include "nsICacheEntryDoomCallback.h"
 
 #include "nsCacheService.h"
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIURI.h"
 #include "nsNetCID.h"
+#include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace net {
 
 AppCacheStorage::AppCacheStorage(nsILoadContextInfo* aInfo,
                                  nsIApplicationCache* aAppCache)
@@ -55,17 +56,17 @@ NS_IMETHODIMP AppCacheStorage::AsyncOpen
 
   if (!appCache) {
     LOG(("AppCacheStorage::AsyncOpenURI entry not found in any appcache, giving up"));
     aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_CACHE_KEY_NOT_FOUND);
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString cacheKey;
   rv = noRefURI->GetAsciiSpec(cacheKey);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // This is the only way how to recognize appcache data by the anonymous
   // flag.  There is no way to switch to e.g. a different session, because
--- a/netwerk/cache2/CacheStorage.cpp
+++ b/netwerk/cache2/CacheStorage.cpp
@@ -11,16 +11,17 @@
 #include "OldWrappers.h"
 
 #include "nsICacheEntryDoomCallback.h"
 
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIURI.h"
 #include "nsNetCID.h"
+#include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS(CacheStorage, nsICacheStorage)
 
 CacheStorage::CacheStorage(nsILoadContextInfo* aInfo,
@@ -59,17 +60,17 @@ NS_IMETHODIMP CacheStorage::AsyncOpenURI
   NS_ENSURE_ARG(aURI);
   NS_ENSURE_ARG(aCallback);
 
   nsresult rv;
 
   bool truncate = aFlags & nsICacheStorage::OPEN_TRUNCATE;
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString asciiSpec;
   rv = noRefURI->GetAsciiSpec(asciiSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIApplicationCache> appCache;
   if (LookupAppCache()) {
@@ -115,17 +116,17 @@ NS_IMETHODIMP CacheStorage::OpenTruncate
                                          nsICacheEntry **aCacheEntry)
 {
   if (!CacheStorageService::Self())
     return NS_ERROR_NOT_INITIALIZED;
 
   nsresult rv;
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString asciiSpec;
   rv = noRefURI->GetAsciiSpec(asciiSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<CacheEntryHandle> handle;
   rv = CacheStorageService::Self()->AddStorageEntry(
@@ -151,17 +152,17 @@ NS_IMETHODIMP CacheStorage::Exists(nsIUR
   NS_ENSURE_ARG(aResult);
 
   if (!CacheStorageService::Self())
     return NS_ERROR_NOT_INITIALIZED;
 
   nsresult rv;
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString asciiSpec;
   rv = noRefURI->GetAsciiSpec(asciiSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CacheStorageService::Self()->CheckStorageEntry(
     this, asciiSpec, aIdExtension, aResult);
@@ -178,17 +179,17 @@ CacheStorage::GetCacheIndexEntryAttrs(ns
   NS_ENSURE_ARG(aSizeInKB);
   if (!CacheStorageService::Self()) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   nsresult rv;
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString asciiSpec;
   rv = noRefURI->GetAsciiSpec(asciiSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CacheStorageService::Self()->GetCacheIndexEntryAttrs(
     this, asciiSpec, aIdExtension, aHasAltData, aSizeInKB);
@@ -198,17 +199,17 @@ NS_IMETHODIMP CacheStorage::AsyncDoomURI
                                          nsICacheEntryDoomCallback* aCallback)
 {
   if (!CacheStorageService::Self())
     return NS_ERROR_NOT_INITIALIZED;
 
   nsresult rv;
 
   nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString asciiSpec;
   rv = noRefURI->GetAsciiSpec(asciiSpec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CacheStorageService::Self()->DoomStorageEntry(
     this, asciiSpec, aIdExtension, aCallback);
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -1107,17 +1107,17 @@ nsresult _OldStorage::AssembleCacheKey(n
       aCacheKey.AssignLiteral("anon&");
     }
 
     if (!aIdExtension.IsEmpty()) {
       aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading());
     }
 
     nsCOMPtr<nsIURI> noRefURI;
-    rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+    rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(noRefURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = noRefURI->GetAsciiSpec(uriSpec);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!aCacheKey.IsEmpty()) {
       aCacheKey.AppendLiteral("uri=");
     }
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -424,19 +424,19 @@ nsNestedAboutURI::StartClone(nsSimpleURI
     // aside from the "new ns***URI()" call.
     NS_ENSURE_TRUE(mInnerURI, nullptr);
 
     nsCOMPtr<nsIURI> innerClone;
     nsresult rv = NS_OK;
     if (aRefHandlingMode == eHonorRef) {
         innerClone = mInnerURI;
     } else if (aRefHandlingMode == eReplaceRef) {
-        rv = mInnerURI->CloneWithNewRef(aNewRef, getter_AddRefs(innerClone));
+        rv = NS_GetURIWithNewRef(mInnerURI, aNewRef, getter_AddRefs(innerClone));
     } else {
-        rv = mInnerURI->CloneIgnoringRef(getter_AddRefs(innerClone));
+        rv = NS_GetURIWithoutRef(mInnerURI, getter_AddRefs(innerClone));
     }
 
     if (NS_FAILED(rv)) {
         return nullptr;
     }
 
     nsNestedAboutURI* url = new nsNestedAboutURI(innerClone, mBaseURI);
     SetRefOnClone(url, aRefHandlingMode, aNewRef);
--- a/netwerk/protocol/data/nsDataChannel.cpp
+++ b/netwerk/protocol/data/nsDataChannel.cpp
@@ -48,17 +48,17 @@ nsDataChannel::OpenContentStream(bool as
 
     nsresult rv;
 
     // In order to avoid potentially building up a new path including the
     // ref portion of the URI, which we don't care about, we clone a version
     // of the URI that does not have a ref and in most cases should share
     // string buffers with the original URI.
     nsCOMPtr<nsIURI> uri;
-    rv = URI()->CloneIgnoringRef(getter_AddRefs(uri));
+    rv = NS_GetURIWithoutRef(URI(), getter_AddRefs(uri));
     if (NS_FAILED(rv))
         return rv;
 
     nsAutoCString path;
     rv = uri->GetPathQueryRef(path);
     if (NS_FAILED(rv))
         return rv;
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1783,19 +1783,19 @@ HttpBaseChannel::SetReferrerWithPolicy(n
   }
 
   nsCOMPtr<nsIURI> clone;
   //
   // we need to clone the referrer, so we can:
   //  (1) modify it
   //  (2) keep a reference to it after returning from this function
   //
-  // Use CloneIgnoringRef to strip away any fragment per RFC 2616 section 14.36
+  // Strip away any fragment per RFC 2616 section 14.36
   // and Referrer Policy section 6.3.5.
-  rv = referrer->CloneIgnoringRef(getter_AddRefs(clone));
+  rv = NS_GetURIWithoutRef(referrer, getter_AddRefs(clone));
   if (NS_FAILED(rv)) return rv;
 
   nsAutoCString currentHost;
   nsAutoCString referrerHost;
 
   rv = mURI->GetAsciiHost(currentHost);
   if (NS_FAILED(rv)) return rv;
 
@@ -1830,17 +1830,17 @@ HttpBaseChannel::SetReferrerWithPolicy(n
     // this falls back on using host if eTLDService does not work
     if (!currentDomain.Equals(referrerDomain))
       return NS_OK;
   }
 
   // send spoofed referrer if desired
   if (userSpoofReferrerSource) {
     nsCOMPtr<nsIURI> mURIclone;
-    rv = mURI->CloneIgnoringRef(getter_AddRefs(mURIclone));
+    rv = NS_GetURIWithoutRef(mURI, getter_AddRefs(mURIclone));
     if (NS_FAILED(rv)) return rv;
     clone = mURIclone;
     currentHost = referrerHost;
   }
 
   // strip away any userpass; we don't want to be giving out passwords ;-)
   // This is required by Referrer Policy stripping algorithm.
   rv = NS_MutateURI(clone)
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -8181,17 +8181,17 @@ nsHttpChannel::GetOfflineCacheEntryAsFor
 }
 
 nsresult
 nsHttpChannel::OfflineCacheEntryAsForeignMarker::MarkAsForeign()
 {
     nsresult rv;
 
     nsCOMPtr<nsIURI> noRefURI;
-    rv = mCacheURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+    rv = NS_GetURIWithoutRef(mCacheURI, getter_AddRefs(noRefURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsAutoCString spec;
     rv = noRefURI->GetAsciiSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return mApplicationCache->MarkEntry(spec,
                                         nsIApplicationCache::ITEM_FOREIGN);
--- a/netwerk/test/unit/test_URIs.js
+++ b/netwerk/test/unit/test_URIs.js
@@ -334,17 +334,17 @@ function do_test_uri_basic(aTest) {
     do_info("relURI.pathQueryRef = " + relURI.pathQueryRef + ", was " + URI.pathQueryRef);
     URI = relURI;
     do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
   }
 
   // Sanity-check
   do_info("testing " + aTest.spec + " equals a clone of itself");
   do_check_uri_eq(URI, URI.mutate().finalize());
-  do_check_uri_eqExceptRef(URI, URI.cloneIgnoringRef());
+  do_check_uri_eqExceptRef(URI, URI.mutate().setRef("").finalize());
   do_info("testing " + aTest.spec + " instanceof nsIURL");
   Assert.equal(URI instanceof Ci.nsIURL, aTest.nsIURL);
   do_info("testing " + aTest.spec + " instanceof nsINestedURI");
   Assert.equal(URI instanceof Ci.nsINestedURI,
                aTest.nsINestedURI);
 
   do_info("testing that " + aTest.spec + " throws or returns false " +
           "from equals(null)");
@@ -414,32 +414,34 @@ function do_test_uri_with_hash_suffix(aT
   do_info("testing " + aTest.spec +
           " is equalExceptRef to self with '" + aSuffix + "' appended");
   do_check_uri_eqExceptRef(origURI, testURI);
 
   Assert.equal(testURI.hasRef, true);
 
   if (!origURI.ref) {
     // These tests fail if origURI has a ref
-    do_info("testing cloneIgnoringRef on " + testURI.spec +
+    do_info("testing setRef('') on " + testURI.spec +
             " is equal to no-ref version but not equal to ref version");
-    var cloneNoRef = testURI.cloneIgnoringRef();
+    var cloneNoRef = testURI.mutate().setRef("").finalize(); // we used to clone here.
+    do_info("cloneNoRef: " + cloneNoRef.spec + " hasRef: " + cloneNoRef.hasRef);
+    do_info("testURI: " + testURI.spec + " hasRef: " + testURI.hasRef);
     do_check_uri_eq(cloneNoRef, origURI);
     Assert.ok(!cloneNoRef.equals(testURI));
 
     do_info("testing cloneWithNewRef on " + testURI.spec +
             " with an empty ref is equal to no-ref version but not equal to ref version");
-    var cloneNewRef = testURI.cloneWithNewRef("");
+    var cloneNewRef = testURI.mutate().setRef("").finalize();
     do_check_uri_eq(cloneNewRef, origURI);
     do_check_uri_eq(cloneNewRef, cloneNoRef);
     Assert.ok(!cloneNewRef.equals(testURI));
 
     do_info("testing cloneWithNewRef on " + origURI.spec +
             " with the same new ref is equal to ref version and not equal to no-ref version");
-    cloneNewRef = origURI.cloneWithNewRef(aSuffix);
+    cloneNewRef = origURI.mutate().setRef(aSuffix).finalize();
     do_check_uri_eq(cloneNewRef, testURI);
     Assert.ok(cloneNewRef.equals(testURI));
   }
 
   do_check_property(aTest, testURI, "scheme");
   do_check_property(aTest, testURI, "prePath");
   if (!origURI.ref) {
     // These don't work if it's a ref already because '+' doesn't give the right result
--- a/netwerk/test/unit/test_URIs2.js
+++ b/netwerk/test/unit/test_URIs2.js
@@ -443,17 +443,17 @@ function do_test_uri_basic(aTest) {
     do_info("relURI.pathQueryRef = " + relURI.pathQueryRef + ", was " + URI.pathQueryRef);
     URI = relURI;
     do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
   }
 
   // Sanity-check
   do_info("testing " + aTest.spec + " equals a clone of itself");
   do_check_uri_eq(URI, URI.mutate().finalize());
-  do_check_uri_eqExceptRef(URI, URI.cloneIgnoringRef());
+  do_check_uri_eqExceptRef(URI, URI.mutate().setRef("").finalize());
   do_info("testing " + aTest.spec + " instanceof nsIURL");
   Assert.equal(URI instanceof Ci.nsIURL, aTest.nsIURL);
   do_info("testing " + aTest.spec + " instanceof nsINestedURI");
   Assert.equal(URI instanceof Ci.nsINestedURI,
                aTest.nsINestedURI);
 
   do_info("testing that " + aTest.spec + " throws or returns false " +
           "from equals(null)");
@@ -525,17 +525,17 @@ function do_test_uri_with_hash_suffix(aT
   do_check_uri_eqExceptRef(origURI, testURI);
 
   Assert.equal(testURI.hasRef, true);
 
   if (!origURI.ref) {
     // These tests fail if origURI has a ref
     do_info("testing cloneIgnoringRef on " + testURI.spec +
             " is equal to no-ref version but not equal to ref version");
-    var cloneNoRef = testURI.cloneIgnoringRef();
+    var cloneNoRef = testURI.mutate().setRef("").finalize();
     do_check_uri_eq(cloneNoRef, origURI);
     Assert.ok(!cloneNoRef.equals(testURI));
   }
 
   do_check_property(aTest, testURI, "scheme");
   do_check_property(aTest, testURI, "prePath");
   if (!origURI.ref) {
     // These don't work if it's a ref already because '+' doesn't give the right result
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -465,17 +465,17 @@ ProxyMessenger = {
 
       let browser = tab.linkedBrowser || tab.browser;
 
       // Options panels in the add-on manager currently require
       // special-casing, since their message managers aren't currently
       // connected to the tab's top-level message manager. To deal with
       // this, we find the options <browser> for the tab, and use that
       // directly, insteead.
-      if (browser.currentURI.cloneIgnoringRef().spec === "about:addons") {
+      if (browser.currentURI.specIgnoringRef === "about:addons") {
         let optionsBrowser = browser.contentDocument.querySelector(".inline-options-browser");
         if (optionsBrowser) {
           browser = optionsBrowser;
         }
       }
 
       return {messageManager: browser.messageManager, xulBrowser: browser};
     }
--- a/toolkit/components/extensions/ExtensionPolicyService.cpp
+++ b/toolkit/components/extensions/ExtensionPolicyService.cpp
@@ -322,17 +322,17 @@ ExtensionPolicyService::CheckWindow(nsPI
   nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
   if (!doc || doc->IsInitialDocument() ||
       doc->GetReadyStateEnum() == nsIDocument::READYSTATE_UNINITIALIZED) {
     return;
   }
 
   nsCOMPtr<nsIURI> docUri = doc->GetDocumentURI();
   nsCOMPtr<nsIURI> uri;
-  if (!docUri || NS_FAILED(docUri->CloneIgnoringRef(getter_AddRefs(uri))) ||
+  if (!docUri || NS_FAILED(NS_GetURIWithoutRef(docUri, getter_AddRefs(uri))) ||
       !NS_IsAboutBlank(uri)) {
     return;
   }
 
   CheckContentScripts(aWindow, false);
 }
 
 void
--- a/toolkit/components/extensions/MatchPattern.cpp
+++ b/toolkit/components/extensions/MatchPattern.cpp
@@ -184,17 +184,17 @@ URLInfo::Spec() const
   }
   return mSpec;
 }
 
 nsIURI*
 URLInfo::URINoRef() const
 {
   if (!mURINoRef) {
-    if (NS_FAILED(mURI->CloneIgnoringRef(getter_AddRefs(mURINoRef)))) {
+    if (NS_FAILED(NS_GetURIWithoutRef(mURI, getter_AddRefs(mURINoRef)))) {
       mURINoRef = mURI;
     }
   }
   return mURINoRef;
 }
 
 bool
 URLInfo::InheritsPrincipal() const
--- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp
@@ -81,19 +81,18 @@ private:
 
 namespace {
 
 nsresult
 DropReferenceFromURL(nsCOMPtr<nsIURI>& aURI)
 {
     // XXXdholbert If this SetRef fails, callers of this method probably
     // want to call aURI->CloneIgnoringRef() and use the result of that.
-    return NS_MutateURI(aURI)
-             .SetRef(EmptyCString())
-             .Finalize(aURI);
+    nsCOMPtr<nsIURI> uri(aURI);
+    return NS_GetURIWithoutRef(uri, getter_AddRefs(aURI));
 }
 
 void
 LogToConsole(const char * message, nsOfflineCacheUpdateItem * item = nullptr)
 {
     nsCOMPtr<nsIConsoleService> consoleService =
         do_GetService(NS_CONSOLESERVICE_CONTRACTID);
     if (consoleService)
@@ -1242,17 +1241,17 @@ nsOfflineCacheUpdate::~nsOfflineCacheUpd
 
 /* static */
 nsresult
 nsOfflineCacheUpdate::GetCacheKey(nsIURI *aURI, nsACString &aKey)
 {
     aKey.Truncate();
 
     nsCOMPtr<nsIURI> newURI;
-    nsresult rv = aURI->CloneIgnoringRef(getter_AddRefs(newURI));
+    nsresult rv = NS_GetURIWithoutRef(aURI, getter_AddRefs(newURI));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = newURI->GetAsciiSpec(aKey);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }