Bug 1434163 - Make all nsIURI attributes readonly r=mayhemer
authorValentin Gosu <valentin.gosu@gmail.com>
Tue, 27 Feb 2018 00:07:48 +0100
changeset 406469 74fc2052319834612c33a454e1cee999fcbb71dc
parent 406468 b8e64a94e635899705cea4967914236162077d56
child 406470 e0a1ba39c48913e4e88efe4fa289c23454ff5181
child 406475 e3f41cf7ac017e66d36ecc5ca372303e9606a32d
push id33560
push userdluca@mozilla.com
push dateSun, 04 Mar 2018 10:03:04 +0000
treeherdermozilla-central@e0a1ba39c489 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1434163
milestone60.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 1434163 - Make all nsIURI attributes readonly r=mayhemer MozReview-Commit-ID: KtjO8VWjPF5
caps/NullPrincipalURI.cpp
caps/NullPrincipalURI.h
dom/base/Link.cpp
dom/file/nsHostObjectURI.cpp
dom/file/nsHostObjectURI.h
dom/jsurl/nsJSProtocolHandler.h
image/decoders/icon/nsIconURI.cpp
image/decoders/icon/nsIconURI.h
modules/libjar/nsJARURI.cpp
modules/libjar/nsJARURI.h
netwerk/base/nsIURI.idl
netwerk/base/nsIURIMutator.idl
netwerk/base/nsSimpleNestedURI.h
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsSimpleURI.h
netwerk/base/nsStandardURL.cpp
netwerk/base/nsStandardURL.h
netwerk/protocol/about/nsAboutProtocolHandler.h
netwerk/protocol/res/SubstitutingProtocolHandler.h
netwerk/test/gtest/TestStandardURL.cpp
--- a/caps/NullPrincipalURI.cpp
+++ b/caps/NullPrincipalURI.cpp
@@ -104,106 +104,100 @@ NullPrincipalURI::GetAsciiSpec(nsACStrin
 
 NS_IMETHODIMP
 NullPrincipalURI::GetHost(nsACString& _host)
 {
   _host.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetHost(const nsACString& aHost)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetHostPort(nsACString& _host)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetHostPort(const nsACString& aHost)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-NullPrincipalURI::SetHostAndPort(const nsACString& aHost)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
 NullPrincipalURI::GetPassword(nsACString& _password)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetPassword(const nsACString& aPassword)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetPathQueryRef(nsACString& _path)
 {
   _path = mPath;
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetPathQueryRef(const nsACString& aPath)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetFilePath(nsACString& aFilePath)
 {
   aFilePath.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetFilePath(const nsACString& aFilePath)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetQuery(nsACString& aQuery)
 {
   aQuery.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetQuery(const nsACString& aQuery)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetQueryWithEncoding(const nsACString& aQuery,
                                        const Encoding* aEncoding)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetRef(nsACString& _ref)
 {
   _ref.Truncate();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetRef(const nsACString& aRef)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetPrePath(nsACString& _prePath)
 {
@@ -212,30 +206,30 @@ NullPrincipalURI::GetPrePath(nsACString&
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetPort(int32_t* _port)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetPort(int32_t aPort)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetScheme(nsACString& _scheme)
 {
   _scheme = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME);
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetScheme(const nsACString& aScheme)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetSpec(nsACString& _spec)
 {
@@ -264,29 +258,29 @@ NullPrincipalURI::SetSpecInternal(const 
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetUsername(nsACString& _username)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetUsername(const nsACString& aUsername)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::GetUserPass(nsACString& _userPass)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
+nsresult
 NullPrincipalURI::SetUserPass(const nsACString& aUserPass)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 NullPrincipalURI::Clone(nsIURI** _newURI)
 {
--- a/caps/NullPrincipalURI.h
+++ b/caps/NullPrincipalURI.h
@@ -21,16 +21,20 @@
 #include "nsID.h"
 #include "nsIURIMutator.h"
 
 // {51fcd543-3b52-41f7-b91b-6b54102236e6}
 #define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
   {0x51fcd543, 0x3b52, 0x41f7, \
     {0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
 
+namespace mozilla {
+class Encoding;
+}
+
 class NullPrincipalURI final : public nsIURI
                              , public nsISizeOf
                              , public nsIIPCSerializableURI
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
   NS_DECL_NSIIPCSERIALIZABLEURI
@@ -47,16 +51,30 @@ private:
   NullPrincipalURI(const NullPrincipalURI& aOther);
 
   ~NullPrincipalURI() {}
 
   nsresult Init();
 
   nsAutoCStringN<NSID_LENGTH> mPath;
 
+  nsresult SetSpecInternal(const nsACString &input);
+  nsresult SetScheme(const nsACString &input);
+  nsresult SetUserPass(const nsACString &input);
+  nsresult SetUsername(const nsACString &input);
+  nsresult SetPassword(const nsACString &input);
+  nsresult SetHostPort(const nsACString &aValue);
+  nsresult SetHost(const nsACString &input);
+  nsresult SetPort(int32_t port);
+  nsresult SetPathQueryRef(const nsACString &input);
+  nsresult SetRef(const nsACString &input);
+  nsresult SetFilePath(const nsACString &input);
+  nsresult SetQuery(const nsACString &input);
+  nsresult SetQueryWithEncoding(const nsACString &input, const mozilla::Encoding* encoding);
+
 public:
   class Mutator final
       : public nsIURIMutator
       , public BaseURIMutator<NullPrincipalURI>
   {
     NS_DECL_ISUPPORTS
     NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
 
--- a/dom/base/Link.cpp
+++ b/dom/base/Link.cpp
@@ -859,16 +859,17 @@ Link::UnregisterFromHistory()
       }
     }
   }
 }
 
 already_AddRefed<nsIURI>
 Link::GetURIToMutate()
 {
+  MOZ_ASSERT(false, "TODO: REMOVE THIS METHOD");
   nsCOMPtr<nsIURI> uri(GetURI());
   if (!uri) {
     return nullptr;
   }
   nsCOMPtr<nsIURI> clone;
   (void)uri->Clone(getter_AddRefs(clone));
   return clone.forget();
 }
--- a/dom/file/nsHostObjectURI.cpp
+++ b/dom/file/nsHostObjectURI.cpp
@@ -151,17 +151,17 @@ nsHostObjectURI::Deserialize(const mozil
 
   // If this fails, we still want to complete the operation. Probably this
   // blobURL has been revoked in the meantime.
   NS_GetBlobForBlobURI(this, getter_AddRefs(mBlobImpl));
 
   return true;
 }
 
-NS_IMETHODIMP
+nsresult
 nsHostObjectURI::SetScheme(const nsACString& aScheme)
 {
   // Disallow setting the scheme, since that could cause us to be associated
   // with a different protocol handler that doesn't expect us to be carrying
   // around a principal with nsIURIWithPrincipal.
   return NS_ERROR_FAILURE;
 }
 
--- a/dom/file/nsHostObjectURI.h
+++ b/dom/file/nsHostObjectURI.h
@@ -44,18 +44,16 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIURIWITHBLOBIMPL
   NS_DECL_NSIURIWITHPRINCIPAL
   NS_DECL_NSISERIALIZABLE
   NS_DECL_NSICLASSINFO
   NS_DECL_NSIIPCSERIALIZABLEURI
 
-  NS_IMETHOD SetScheme(const nsACString &aProtocol) override;
-
   // Override CloneInternal() and EqualsInternal()
   virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
                                  const nsACString& newRef,
                                  nsIURI** aClone) override;
   virtual nsresult EqualsInternal(nsIURI* aOther,
                                   RefHandlingEnum aRefHandlingMode,
                                   bool* aResult) override;
 
@@ -73,16 +71,18 @@ public:
   void ForgetBlobImpl();
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
   RefPtr<mozilla::dom::BlobImpl> mBlobImpl;
 
 protected:
   virtual ~nsHostObjectURI() {}
 
+  nsresult SetScheme(const nsACString &aProtocol) override;
+
 public:
   class Mutator final
     : public nsIURIMutator
     , public BaseURIMutator<nsHostObjectURI>
     , public nsIBlobURIMutator
     , public nsIPrincipalURIMutator
   {
     NS_DECL_ISUPPORTS
@@ -110,15 +110,17 @@ public:
     }
 
     explicit Mutator() { }
   private:
     virtual ~Mutator() { }
 
     friend class nsHostObjectURI;
   };
+
+  friend BaseURIMutator<nsHostObjectURI>;
 };
 
 #define NS_HOSTOBJECTURI_CID \
 { 0xf5475c51, 0x59a7, 0x4757, \
   { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } }
 
 #endif /* nsHostObjectURI_h */
--- a/dom/jsurl/nsJSProtocolHandler.h
+++ b/dom/jsurl/nsJSProtocolHandler.h
@@ -115,11 +115,13 @@ public:
         NS_DEFINE_NSIMUTATOR_COMMON
 
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
         friend class nsJSURI;
     };
+
+    friend BaseURIMutator<nsJSURI>;
 };
 
 #endif /* nsJSProtocolHandler_h___ */
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -323,155 +323,149 @@ nsMozIconURI::GetPrePath(nsACString& pre
 
 NS_IMETHODIMP
 nsMozIconURI::GetScheme(nsACString& aScheme)
 {
   aScheme = "moz-icon";
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetScheme(const nsACString& aScheme)
 {
   // doesn't make sense to set the scheme of a moz-icon URL
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetUsername(nsACString& aUsername)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetUsername(const nsACString& aUsername)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetPassword(nsACString& aPassword)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetPassword(const nsACString& aPassword)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetUserPass(nsACString& aUserPass)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetUserPass(const nsACString& aUserPass)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetHostPort(nsACString& aHostPort)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetHostPort(const nsACString& aHostPort)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsMozIconURI::SetHostAndPort(const nsACString& aHostPort)
-{
-  return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
 nsMozIconURI::GetHost(nsACString& aHost)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetHost(const nsACString& aHost)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetPort(int32_t* aPort)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetPort(int32_t aPort)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetPathQueryRef(nsACString& aPath)
 {
   aPath.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetPathQueryRef(const nsACString& aPath)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetFilePath(nsACString& aFilePath)
 {
   aFilePath.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetFilePath(const nsACString& aFilePath)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetQuery(nsACString& aQuery)
 {
   aQuery.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetQuery(const nsACString& aQuery)
 {
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetQueryWithEncoding(const nsACString& aQuery,
                                    const Encoding* aEncoding)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::GetRef(nsACString& aRef)
 {
   aRef.Truncate();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsMozIconURI::SetRef(const nsACString& aRef)
 {
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::Equals(nsIURI* other, bool* result)
 {
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -9,16 +9,19 @@
 
 #include "nsIIconURI.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIIPCSerializableURI.h"
 #include "nsINestedURI.h"
 #include "nsIURIMutator.h"
 
+namespace mozilla {
+class Encoding;
+}
 
 class nsMozIconURI final
   : public nsIMozIconURI
   , public nsIIPCSerializableURI
   , public nsINestedURI
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -40,16 +43,31 @@ protected:
   nsCString mFileName; // for if we don't have an actual file path, we're just
                        // given a filename with an extension
   nsCString mStockIcon;
   int32_t mIconSize;   // -1 if not specified, otherwise index into
                        // kSizeStrings
   int32_t mIconState;  // -1 if not specified, otherwise index into
                        // kStateStrings
 
+private:
+  nsresult SetSpecInternal(const nsACString &input);
+  nsresult SetScheme(const nsACString &input);
+  nsresult SetUserPass(const nsACString &input);
+  nsresult SetUsername(const nsACString &input);
+  nsresult SetPassword(const nsACString &input);
+  nsresult SetHostPort(const nsACString &aValue);
+  nsresult SetHost(const nsACString &input);
+  nsresult SetPort(int32_t port);
+  nsresult SetPathQueryRef(const nsACString &input);
+  nsresult SetRef(const nsACString &input);
+  nsresult SetFilePath(const nsACString &input);
+  nsresult SetQuery(const nsACString &input);
+  nsresult SetQueryWithEncoding(const nsACString &input, const mozilla::Encoding* encoding);
+
 public:
   class Mutator final
       : public nsIURIMutator
       , public BaseURIMutator<nsMozIconURI>
   {
     NS_DECL_ISUPPORTS
     NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
 
@@ -79,11 +97,13 @@ public:
     }
 
     explicit Mutator() { }
   private:
     virtual ~Mutator() { }
 
     friend class nsMozIconURI;
   };
+
+  friend BaseURIMutator<nsMozIconURI>;
 };
 
 #endif // mozilla_image_decoders_icon_nsIconURI_h
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -413,110 +413,104 @@ nsJARURI::GetPrePath(nsACString &prePath
 
 NS_IMETHODIMP
 nsJARURI::GetScheme(nsACString &aScheme)
 {
     aScheme = "jar";
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetScheme(const nsACString &aScheme)
 {
     // doesn't make sense to set the scheme of a jar: URL
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetUserPass(nsACString &aUserPass)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetUserPass(const nsACString &aUserPass)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetUsername(nsACString &aUsername)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetUsername(const nsACString &aUsername)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetPassword(nsACString &aPassword)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetPassword(const nsACString &aPassword)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetHostPort(nsACString &aHostPort)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetHostPort(const nsACString &aHostPort)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsJARURI::SetHostAndPort(const nsACString &aHostPort)
-{
-    return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
 nsJARURI::GetHost(nsACString &aHost)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetHost(const nsACString &aHost)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetPort(int32_t *aPort)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetPort(int32_t aPort)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::GetPathQueryRef(nsACString &aPath)
 {
     nsAutoCString entrySpec;
     mJAREntry->GetSpec(entrySpec);
     return FormatSpec(entrySpec, aPath, false);
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetPathQueryRef(const nsACString &aPath)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsJARURI::GetAsciiSpec(nsACString &aSpec)
 {
@@ -656,54 +650,54 @@ nsJARURI::Resolve(const nsACString &rela
 // nsIURL methods:
 
 NS_IMETHODIMP
 nsJARURI::GetFilePath(nsACString& filePath)
 {
     return mJAREntry->GetFilePath(filePath);
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetFilePath(const nsACString& filePath)
 {
     return NS_MutateURI(mJAREntry)
              .SetFilePath(filePath)
              .Finalize(mJAREntry);
 }
 
 NS_IMETHODIMP
 nsJARURI::GetQuery(nsACString& query)
 {
     return mJAREntry->GetQuery(query);
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetQuery(const nsACString& query)
 {
     return NS_MutateURI(mJAREntry)
              .SetQuery(query)
              .Finalize(mJAREntry);
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetQueryWithEncoding(const nsACString& query,
                                const Encoding* encoding)
 {
     return NS_MutateURI(mJAREntry)
              .SetQueryWithEncoding(query, encoding)
              .Finalize(mJAREntry);
 }
 
 NS_IMETHODIMP
 nsJARURI::GetRef(nsACString& ref)
 {
     return mJAREntry->GetRef(ref);
 }
 
-NS_IMETHODIMP
+nsresult
 nsJARURI::SetRef(const nsACString& ref)
 {
     return NS_MutateURI(mJAREntry)
              .SetRef(ref)
              .Finalize(mJAREntry);
 }
 
 NS_IMETHODIMP
--- a/modules/libjar/nsJARURI.h
+++ b/modules/libjar/nsJARURI.h
@@ -75,20 +75,16 @@ protected:
 
     // enum used in a few places to specify how .ref attribute should be handled
     enum RefHandlingEnum {
         eIgnoreRef,
         eHonorRef,
         eReplaceRef
     };
 
-    nsresult SetFileNameInternal(const nsACString& fileName);
-    nsresult SetFileBaseNameInternal(const nsACString& fileBaseName);
-    nsresult SetFileExtensionInternal(const nsACString& fileExtension);
-
     // Helper to share code between Equals methods.
     virtual nsresult EqualsInternal(nsIURI* other,
                                     RefHandlingEnum refHandlingMode,
                                     bool* result);
 
     // Helpers to share code between Clone methods.
     nsresult CloneWithJARFileInternal(nsIURI *jarFile,
                                       RefHandlingEnum refHandlingMode,
@@ -98,16 +94,35 @@ protected:
                                       const nsACString& newRef,
                                       nsIJARURI **result);
     nsCOMPtr<nsIURI> mJARFile;
     // mJarEntry stored as a URL so that we can easily access things
     // like extensions, refs, etc.
     nsCOMPtr<nsIURL> mJAREntry;
     nsCString        mCharsetHint;
 
+private:
+    nsresult SetSpecInternal(const nsACString &input);
+    nsresult SetScheme(const nsACString &input);
+    nsresult SetUserPass(const nsACString &input);
+    nsresult SetUsername(const nsACString &input);
+    nsresult SetPassword(const nsACString &input);
+    nsresult SetHostPort(const nsACString &aValue);
+    nsresult SetHost(const nsACString &input);
+    nsresult SetPort(int32_t port);
+    nsresult SetPathQueryRef(const nsACString &input);
+    nsresult SetRef(const nsACString &input);
+    nsresult SetFilePath(const nsACString &input);
+    nsresult SetQuery(const nsACString &input);
+    nsresult SetQueryWithEncoding(const nsACString &input, const Encoding* encoding);
+
+    nsresult SetFileNameInternal(const nsACString& fileName);
+    nsresult SetFileBaseNameInternal(const nsACString& fileBaseName);
+    nsresult SetFileExtensionInternal(const nsACString& fileExtension);
+
 public:
     class Mutator final
         : public nsIURIMutator
         , public BaseURIMutator<nsJARURI>
         , public nsIURLMutator
     {
         NS_DECL_ISUPPORTS
         NS_FORWARD_SAFE_NSIURISETTERS_RET(mURI)
@@ -115,13 +130,15 @@ public:
         NS_DECL_NSIURLMUTATOR
 
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
         friend class nsJARURI;
     };
+
+    friend BaseURIMutator<nsJARURI>;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsJARURI, NS_THIS_JARURI_IMPL_CID)
 
 #endif // nsJARURI_h__
--- a/netwerk/base/nsIURI.idl
+++ b/netwerk/base/nsIURI.idl
@@ -2,17 +2,18 @@
 /* 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/. */
 
 #include "nsISupports.idl"
 
 /**
  * URIs are essentially structured names for things -- anything. This interface
- * provides accessors to set and query the most basic components of an URI.
+ * provides accessors to get the most basic components of an URI.
+ * If you need to change some parts of the URI use nsIURIMutator.
  * Subclasses, including nsIURL, impose greater structure on the URI.
  *
  * This interface follows Tim Berners-Lee's URI spec (RFC3986) [1], where the
  * basic URI components are defined as such:
  * <pre>
  *      ftp://username:password@hostname:portnumber/pathname?query#ref
  *      \ /   \               / \      / \        /\       / \   / \ /
  *       -     ---------------   ------   --------  -------   ---   -
@@ -81,31 +82,16 @@ interface nsIURI : nsISupports
 
     /**
      * Returns a string representation of the URI.
      *
      * Some characters may be escaped.
      */
     readonly attribute AUTF8String spec;
 
-    /*
-     * This method should only be called by nsIURIMutator or C++ unit tests.
-     *
-     * Setting the spec causes
-     * the new spec to be parsed per the rules for the scheme the URI
-     * currently has.  In particular, setting the spec to a URI string with a
-     * different scheme will generally produce incorrect results; no one
-     * outside of a protocol handler implementation should be doing that.  If
-     * the URI stores information from the nsIIOService.newURI call used to
-     * create it other than just the parsed string, then behavior of this
-     * information on setting the spec attribute is undefined.
-     */
-    [noscript,notxpcom,nostdcall]
-    nsresult setSpecInternal(in ACString aSpec);
-
 %{ C++
     // An infallible wrapper for GetSpec() that returns a failure indication
     // string if GetSpec() fails. It is most useful for creating
     // logging/warning/error messages produced for human consumption, and when
     // matching a URI spec against a fixed spec such as about:blank.
     nsCString GetSpecOrDefault()
     {
         nsCString spec;
@@ -122,77 +108,64 @@ interface nsIURI : nsISupports
      * before the path.  This is useful for authentication or managing sessions.
      *
      * Some characters may be escaped.
      */
     readonly attribute AUTF8String prePath;
 
     /**
      * The Scheme is the protocol to which this URI refers.  The scheme is
-     * restricted to the US-ASCII charset per RFC3986.  Setting this is
-     * highly discouraged outside of a protocol handler implementation, since
-     * that will generally lead to incorrect results.
+     * restricted to the US-ASCII charset per RFC3986.
      */
-    attribute ACString scheme;
+    readonly attribute ACString scheme;
 
     /**
      * The username:password (or username only if value doesn't contain a ':')
      *
      * Some characters may be escaped.
      */
-    attribute AUTF8String userPass;
+    readonly attribute AUTF8String userPass;
 
     /**
      * The optional username and password, assuming the preHost consists of
      * username:password.
      *
      * Some characters may be escaped.
      */
-    attribute AUTF8String username;
-    attribute AUTF8String password;
+    readonly attribute AUTF8String username;
+    readonly attribute AUTF8String password;
 
     /**
      * The host:port (or simply the host, if port == -1).
-     *
-     * If this attribute is set to a value that only has a host part, the port
-     * will not be reset. To reset the port as well use setHostAndPort.
-     * If setting the host succeeds, this method will return NS_OK, even if
-     * setting the port fails (error in parsing the port, or value out of range)
      */
-    attribute AUTF8String hostPort;
-
-    /**
-     * This function will always set a host and a port. If the port part is
-     * empty, the value of the port will be set to the default value.
-     */
-    void setHostAndPort(in AUTF8String hostport);
+    readonly attribute AUTF8String hostPort;
 
     /**
      * The host is the internet domain name to which this URI refers.  It could
      * be an IPv4 (or IPv6) address literal. Otherwise it is an ASCII or punycode
      * encoded string.
      */
-    attribute AUTF8String host;
+    readonly attribute AUTF8String host;
 
     /**
      * A port value of -1 corresponds to the protocol's default port (eg. -1
      * implies port 80 for http URIs).
      */
-    attribute long port;
+    readonly attribute long port;
 
     /**
      * The path, typically including at least a leading '/' (but may also be
      * empty, depending on the protocol).
      *
      * Some characters may be escaped.
      *
      * This attribute contains query and ref parts for historical reasons.
      * Use the 'filePath' attribute if you do not want those parts included.
      */
-    attribute AUTF8String pathQueryRef;
+    readonly attribute AUTF8String pathQueryRef;
 
 
     /************************************************************************
      * An URI supports the following methods:
      */
 
     /**
      * URI equivalence test (not a strict string comparison).
@@ -252,17 +225,17 @@ interface nsIURI : nsISupports
      */
 
     /**
      * Returns the reference portion (the part after the "#") of the URI.
      * If there isn't one, an empty string is returned.
      *
      * Some characters may be escaped.
      */
-    attribute AUTF8String ref;
+    readonly attribute AUTF8String ref;
 
     /**
      * URI equivalence test (not a strict string comparison), ignoring
      * the value of the .ref member.
      *
      * eg. http://foo.com/# == http://foo.com/
      *     http://foo.com/#aaa == http://foo.com/#bbb
      */
@@ -295,27 +268,25 @@ interface nsIURI : nsISupports
 
     /**
      * Returns a path including the directory and file portions of a
      * URL.  For example, the filePath of "http://host/foo/bar.html#baz"
      * is "/foo/bar.html".
      *
      * Some characters may be escaped.
      */
-    attribute AUTF8String filePath;
+    readonly attribute AUTF8String filePath;
 
     /**
      * Returns the query portion (the part after the "?") of the URL.
      * If there isn't one, an empty string is returned.
      *
      * Some characters may be escaped.
      */
-    attribute AUTF8String query;
-    [noscript]
-    void setQueryWithEncoding(in AUTF8String query, in Encoding encoding);
+    readonly attribute AUTF8String query;
 
     /**
      * If the URI has a punycode encoded hostname, this will hold the UTF8
      * representation of that hostname (if that representation doesn't contain
      * blacklisted characters, and the network.IDN_show_punycode pref is false)
      * Otherwise, if the hostname is ASCII, it will return the same as .asciiHost
      */
     readonly attribute AUTF8String displayHost;
--- a/netwerk/base/nsIURIMutator.idl
+++ b/netwerk/base/nsIURIMutator.idl
@@ -139,20 +139,31 @@ interface nsIURISetSpec : nsISupports
  * let newURI = uri.mutate()
  *                 .setSpec("http://example.com")
  *                 .setQuery("hello")
  *                 .finalize();
  */
 [scriptable, builtinclass, uuid(5403a6ec-99d7-405e-8b45-9f805bbdfcef)]
 interface nsIURISetters : nsIURISetSpec
 {
+  /**
+   * Setting the scheme outside of a protocol handler implementation is highly
+   * discouraged since that will generally lead to incorrect results.
+   */
   [must_use] nsIURIMutator setScheme(in AUTF8String aScheme);
   [must_use] nsIURIMutator setUserPass(in AUTF8String aUserPass);
   [must_use] nsIURIMutator setUsername(in AUTF8String aUsername);
   [must_use] nsIURIMutator setPassword(in AUTF8String aPassword);
+
+  /**
+   * If you setHostPort to a value that only has a host part, the port
+   * will not be reset. To reset the port set it to -1 beforehand.
+   * If setting the host succeeds, this method will return NS_OK, even if
+   * setting the port fails (error in parsing the port, or value out of range)
+   */
   [must_use] nsIURIMutator setHostPort(in AUTF8String aHostPort);
   [must_use] nsIURIMutator setHost(in AUTF8String aHost);
   [must_use] nsIURIMutator setPort(in long aPort);
   [must_use] nsIURIMutator setPathQueryRef(in AUTF8String aPathQueryRef);
   [must_use] nsIURIMutator setRef(in AUTF8String aRef);
   [must_use] nsIURIMutator setFilePath(in AUTF8String aFilePath);
   [must_use] nsIURIMutator setQuery(in AUTF8String aQuery);
   [must_use, noscript] nsIURIMutator setQueryWithEncoding(in AUTF8String query, in Encoding encoding);
--- a/netwerk/base/nsSimpleNestedURI.h
+++ b/netwerk/base/nsSimpleNestedURI.h
@@ -116,14 +116,16 @@ public:
         {
             if (mURI) {
                 mURI->mMutable = true;
             }
         }
 
         friend class nsSimpleNestedURI;
     };
+
+    friend BaseURIMutator<nsSimpleNestedURI>;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* nsSimpleNestedURI_h__ */
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -312,17 +312,17 @@ nsSimpleURI::SetSpecInternal(const nsACS
 
 NS_IMETHODIMP
 nsSimpleURI::GetScheme(nsACString &result)
 {
     result = mScheme;
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetScheme(const nsACString &scheme)
 {
     NS_ENSURE_STATE(mMutable);
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
     if (!net_IsValidScheme(flat)) {
         NS_WARNING("the given url scheme contains invalid characters");
         return NS_ERROR_MALFORMED_URI;
@@ -341,100 +341,92 @@ nsSimpleURI::GetPrePath(nsACString &resu
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetUserPass(nsACString &result)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetUserPass(const nsACString &userPass)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetUsername(nsACString &result)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetUsername(const nsACString &userName)
 {
     NS_ENSURE_STATE(mMutable);
 
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetPassword(nsACString &result)
 {
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetPassword(const nsACString &password)
 {
     NS_ENSURE_STATE(mMutable);
 
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetHostPort(nsACString &result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code may depend on this throwing.
     // Note: If this is changed, change GetAsciiHostPort as well.
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetHostPort(const nsACString &result)
 {
     NS_ENSURE_STATE(mMutable);
 
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-nsSimpleURI::SetHostAndPort(const nsACString &result)
-{
-    NS_ENSURE_STATE(mMutable);
-
-    return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
 nsSimpleURI::GetHost(nsACString &result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code depend on this throwing.
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetHost(const nsACString &host)
 {
     NS_ENSURE_STATE(mMutable);
 
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetPort(int32_t *result)
 {
     // Note: Audit all callers before changing this to return an empty
     // string -- CAPS and UI code may depend on this throwing.
     return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetPort(int32_t port)
 {
     NS_ENSURE_STATE(mMutable);
 
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
@@ -446,17 +438,17 @@ nsSimpleURI::GetPathQueryRef(nsACString 
     }
     if (mIsRefValid) {
         result += NS_LITERAL_CSTRING("#") + mRef;
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetPathQueryRef(const nsACString &aPath)
 {
     NS_ENSURE_STATE(mMutable);
 
     return SetPathQueryRefEscaped(aPath, true);
 }
 nsresult
 nsSimpleURI::SetPathQueryRefEscaped(const nsACString &aPath, bool aNeedsEscape)
@@ -529,17 +521,17 @@ nsSimpleURI::GetRef(nsACString &result)
         result = mRef;
     }
 
     return NS_OK;
 }
 
 // NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
 // string (and will result in .spec and .path having a terminal #).
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetRef(const nsACString &aRef)
 {
     NS_ENSURE_STATE(mMutable);
 
     nsAutoCString ref;
     nsresult rv = NS_EscapeURL(aRef, esc_OnlyNonASCII, ref, fallible);
     if (NS_FAILED(rv)) {
         return rv;
@@ -825,17 +817,17 @@ nsSimpleURI::SizeOfIncludingThis(MallocS
 
 NS_IMETHODIMP
 nsSimpleURI::GetFilePath(nsACString& aFilePath)
 {
     aFilePath = mPath;
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetFilePath(const nsACString& aFilePath)
 {
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSimpleURI::GetQuery(nsACString& aQuery)
 {
@@ -843,17 +835,17 @@ nsSimpleURI::GetQuery(nsACString& aQuery
         MOZ_ASSERT(mQuery.IsEmpty(), "mIsQueryValid/mQuery invariant broken");
         aQuery.Truncate();
     } else {
         aQuery = mQuery;
     }
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetQuery(const nsACString& aQuery)
 {
     NS_ENSURE_STATE(mMutable);
 
     nsAutoCString query;
     nsresult rv = NS_EscapeURL(aQuery, esc_OnlyNonASCII, query, fallible);
     if (NS_FAILED(rv)) {
         return rv;
@@ -873,17 +865,17 @@ nsSimpleURI::SetQuery(const nsACString& 
         mQuery = Substring(query, 1);
     } else {
         mQuery = query;
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsSimpleURI::SetQueryWithEncoding(const nsACString& aQuery,
                                   const Encoding* aEncoding)
 {
     return SetQuery(aQuery);
 }
 
 NS_IMPL_ISUPPORTS(nsSimpleURI::Mutator, nsIURISetters, nsIURIMutator)
 
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -70,16 +70,30 @@ public:
 protected:
     // enum used in a few places to specify how .ref attribute should be handled
     enum RefHandlingEnum {
         eIgnoreRef,
         eHonorRef,
         eReplaceRef
     };
 
+    virtual nsresult SetSpecInternal(const nsACString &input);
+    virtual nsresult SetScheme(const nsACString &input);
+    virtual nsresult SetUserPass(const nsACString &input);
+    virtual nsresult SetUsername(const nsACString &input);
+    virtual nsresult SetPassword(const nsACString &input);
+    virtual nsresult SetHostPort(const nsACString &aValue);
+    virtual nsresult SetHost(const nsACString &input);
+    virtual nsresult SetPort(int32_t port);
+    virtual nsresult SetPathQueryRef(const nsACString &input);
+    virtual nsresult SetRef(const nsACString &input);
+    virtual nsresult SetFilePath(const nsACString &input);
+    virtual nsresult SetQuery(const nsACString &input);
+    virtual nsresult SetQueryWithEncoding(const nsACString &input, const Encoding* encoding);
+
     // Helper to share code between Equals methods.
     virtual nsresult EqualsInternal(nsIURI* other,
                                     RefHandlingEnum refHandlingMode,
                                     bool* result);
 
     // Helper to be used by inherited classes who want to test
     // equality given an assumed nsSimpleURI.  This must NOT check
     // the passed-in other for QI to our CID.
@@ -122,14 +136,16 @@ public:
         NS_DEFINE_NSIMUTATOR_COMMON
 
         explicit Mutator() { }
     private:
         virtual ~Mutator() { }
 
         friend class nsSimpleURI;
     };
+
+    friend BaseURIMutator<nsSimpleURI>;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // nsSimpleURI_h__
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -1643,17 +1643,17 @@ nsStandardURL::SetSpecWithEncoding(const
         LOG((" extension = (%u,%d)\n", mExtension.mPos, mExtension.mLen));
         LOG((" query     = (%u,%d)\n", mQuery.mPos,     mQuery.mLen));
         LOG((" ref       = (%u,%d)\n", mRef.mPos,       mRef.mLen));
     }
 
     return rv;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetScheme(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &scheme = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetScheme [scheme=%s]\n", scheme.get()));
 
@@ -1687,17 +1687,17 @@ nsStandardURL::SetScheme(const nsACStrin
     // ensure new scheme is lowercase
     //
     // XXX the string code unfortunately doesn't provide a ToLowerCase
     //     that operates on a substring.
     net_ToLowerCase((char *) mSpec.get(), mScheme.mLen);
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetUserPass(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &userpass = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetUserPass [userpass=%s]\n", userpass.get()));
 
@@ -1797,17 +1797,17 @@ nsStandardURL::SetUserPass(const nsACStr
     mPassword.mLen = passwordLen;
     if (passwordLen > 0) {
         mPassword.mPos = mUsername.mPos + mUsername.mLen + 1;
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetUsername(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &username = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetUsername [username=%s]\n", username.get()));
 
@@ -1847,17 +1847,17 @@ nsStandardURL::SetUsername(const nsACStr
         mUsername.mLen = escUsername.Length();
         mAuthority.mLen += shift;
         ShiftFromPassword(shift);
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetPassword(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &password = PromiseFlatCString(input);
 
     LOG(("nsStandardURL::SetPassword [password=%s]\n", password.get()));
 
@@ -1926,17 +1926,17 @@ nsStandardURL::FindHostLimit(nsACString:
     if (FindCharInReadable(gHostLimitDigits[i], c, aEnd)) {
       aEnd = c;
     }
   }
 }
 
 // If aValue only has a host part and no port number, the port
 // will not be reset!!!
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetHostPort(const nsACString &aValue)
 {
     ENSURE_MUTABLE();
 
     // We cannot simply call nsIURI::SetHost because that would treat the name as
     // an IPv6 address (like http:://[server:443]/).  We also cannot call
     // nsIURI::SetHostPort because that isn't implemented.  Sadfaces.
 
@@ -1995,29 +1995,17 @@ nsStandardURL::SetHostPort(const nsACStr
         // Failure parsing the port number
         return NS_OK;
     }
 
     Unused << SetPort(port);
     return NS_OK;
 }
 
-// This function is different than SetHostPort in that the port number will be
-// reset as well if aValue parameter does not contain a port port number.
-NS_IMETHODIMP
-nsStandardURL::SetHostAndPort(const nsACString &aValue)
-{
-  // Reset the port and than call SetHostPort. SetHostPort does not reset
-  // the port number.
-  nsresult rv = SetPort(-1);
-  NS_ENSURE_SUCCESS(rv, rv);
-  return SetHostPort(aValue);
-}
-
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetHost(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &hostname = PromiseFlatCString(input);
 
     nsACString::const_iterator start, end;
     hostname.BeginReading(start);
@@ -2116,17 +2104,17 @@ nsStandardURL::SetHost(const nsACString 
         ShiftFromPath(shift);
     }
 
     // Now canonicalize the host to lowercase
     net_ToLowerCase(mSpec.BeginWriting() + mHost.mPos, mHost.mLen);
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetPort(int32_t port)
 {
     ENSURE_MUTABLE();
 
     LOG(("nsStandardURL::SetPort [port=%d]\n", port));
 
     if ((port == mPort) || (mPort == -1 && port == mDefaultPort))
         return NS_OK;
@@ -2190,17 +2178,17 @@ nsStandardURL::ReplacePortInSpec(int32_t
     mSpec.Replace(replacedStart, replacedLen, buf);
 
     // Bookkeeping to reflect the new length:
     int32_t shift = buf.Length() - replacedLen;
     mAuthority.mLen += shift;
     ShiftFromPath(shift);
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetPathQueryRef(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &path = PromiseFlatCString(input);
     LOG(("nsStandardURL::SetPathQueryRef [path=%s]\n", path.get()));
 
     InvalidateCache();
@@ -2837,17 +2825,17 @@ nsStandardURL::GetFileBaseName(nsACStrin
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
 nsStandardURL::GetFileExtension(nsACString &result)
 {
     result = Extension();
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetFilePath(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *filepath = flat.get();
 
     LOG(("nsStandardURL::SetFilePath [filepath=%s]\n", filepath));
@@ -2923,23 +2911,23 @@ nsStandardURL::SetFilePath(const nsACStr
 inline bool
 IsUTFEncoding(const Encoding* aEncoding)
 {
     return aEncoding == UTF_8_ENCODING ||
            aEncoding == UTF_16BE_ENCODING ||
            aEncoding == UTF_16LE_ENCODING;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetQuery(const nsACString &input)
 {
     return SetQueryWithEncoding(input, nullptr);
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetQueryWithEncoding(const nsACString &input,
                                     const Encoding* encoding)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *query = flat.get();
 
@@ -3006,17 +2994,17 @@ nsStandardURL::SetQueryWithEncoding(cons
     if (shift) {
         mQuery.mLen = queryLen;
         mPath.mLen += shift;
         ShiftFromRef(shift);
     }
     return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 nsStandardURL::SetRef(const nsACString &input)
 {
     ENSURE_MUTABLE();
 
     const nsPromiseFlatCString &flat = PromiseFlatCString(input);
     const char *ref = flat.get();
 
     LOG(("nsStandardURL::SetRef [ref=%s]\n", ref));
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -175,16 +175,30 @@ protected:
                          bool copyCached = false);
 
     // Helper for subclass implementation of GetFile().  Subclasses that map
     // URIs to files in a special way should implement this method.  It should
     // ensure that our mFile is initialized, if it's possible.
     // returns NS_ERROR_NO_INTERFACE if the url does not map to a file
     virtual nsresult EnsureFile();
 
+    virtual nsresult SetSpecInternal(const nsACString &input);
+    virtual nsresult SetScheme(const nsACString &input);
+    virtual nsresult SetUserPass(const nsACString &input);
+    virtual nsresult SetUsername(const nsACString &input);
+    virtual nsresult SetPassword(const nsACString &input);
+    virtual nsresult SetHostPort(const nsACString &aValue);
+    virtual nsresult SetHost(const nsACString &input);
+    virtual nsresult SetPort(int32_t port);
+    virtual nsresult SetPathQueryRef(const nsACString &input);
+    virtual nsresult SetRef(const nsACString &input);
+    virtual nsresult SetFilePath(const nsACString &input);
+    virtual nsresult SetQuery(const nsACString &input);
+    virtual nsresult SetQueryWithEncoding(const nsACString &input, const Encoding* encoding);
+
 private:
     nsresult Init(uint32_t urlType, int32_t defaultPort, const nsACString &spec,
                   const char *charset, nsIURI *baseURI);
     nsresult SetDefaultPort(int32_t aNewDefaultPort);
     nsresult SetFile(nsIFile *file);
 
     nsresult SetFileNameInternal(const nsACString &input);
     nsresult SetFileBaseNameInternal(const nsACString &input);
@@ -470,16 +484,18 @@ public:
         : public TemplatedMutator<nsStandardURL>
     {
         NS_DECL_ISUPPORTS
     public:
         explicit Mutator() = default;
     private:
         virtual ~Mutator() = default;
     };
+
+    friend BaseURIMutator<nsStandardURL>;
 };
 
 #define NS_THIS_STANDARDURL_IMPL_CID                 \
 { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */         \
     0xb8e3e97b,                                      \
     0x1ccd,                                          \
     0x4b45,                                          \
     {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
--- a/netwerk/protocol/about/nsAboutProtocolHandler.h
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.h
@@ -133,14 +133,16 @@ public:
         {
             if (mURI) {
                 mURI->mMutable = true;
             }
         }
 
         friend class nsNestedAboutURI;
     };
+
+    friend BaseURIMutator<nsNestedAboutURI>;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* nsAboutProtocolHandler_h___ */
--- a/netwerk/protocol/res/SubstitutingProtocolHandler.h
+++ b/netwerk/protocol/res/SubstitutingProtocolHandler.h
@@ -143,14 +143,16 @@ public:
     RefPtr<SubstitutingURL::Mutator> mutator = new SubstitutingURL::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
       return rv;
     }
     mutator.forget(aMutator);
     return NS_OK;
   }
+
+  friend BaseURIMutator<SubstitutingURL>;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* SubstitutingProtocolHandler_h___ */
--- a/netwerk/test/gtest/TestStandardURL.cpp
+++ b/netwerk/test/gtest/TestStandardURL.cpp
@@ -3,23 +3,27 @@
 
 #include "nsCOMPtr.h"
 #include "nsNetCID.h"
 #include "nsIURL.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIURIMutator.h"
+#define protected public // hack to access setter methods
+#include "../../base/nsStandardURL.h"
+#undef protected
+using mozilla::net::nsStandardURL;
 
 // In nsStandardURL.cpp
 extern nsresult Test_NormalizeIPv4(const nsACString& host, nsCString& result);
 
 
 TEST(TestStandardURL, Simple) {
-    nsCOMPtr<nsIURL> url( do_CreateInstance(NS_STANDARDURL_CONTRACTID) );
+    RefPtr<nsStandardURL> url = new nsStandardURL();
     ASSERT_TRUE(url);
     ASSERT_EQ(url->SetSpecInternal(NS_LITERAL_CSTRING("http://example.com")), NS_OK);
 
     nsAutoCString out;
 
     ASSERT_EQ(url->GetSpec(out), NS_OK);
     ASSERT_TRUE(out == NS_LITERAL_CSTRING("http://example.com/"));
 
@@ -173,17 +177,17 @@ TEST(TestStandardURL, From_test_standard
         nsCString encHost(nonIPv4s[i]);
         ASSERT_EQ(NS_ERROR_FAILURE, Test_NormalizeIPv4(encHost, result));
     }
 }
 
 #define COUNT 10000
 
 MOZ_GTEST_BENCH(TestStandardURL, DISABLED_Perf, [] {
-    nsCOMPtr<nsIURL> url( do_CreateInstance(NS_STANDARDURL_CONTRACTID) );
+    RefPtr<nsStandardURL> url = new nsStandardURL();
     ASSERT_TRUE(url);
     nsAutoCString out;
 
     for (int i = COUNT; i; --i) {
         ASSERT_EQ(url->SetSpecInternal(NS_LITERAL_CSTRING("http://example.com")), NS_OK);
         ASSERT_EQ(url->GetSpec(out), NS_OK);
         url->Resolve(NS_LITERAL_CSTRING("foo.html?q=45"), out);
         url->SetScheme(NS_LITERAL_CSTRING("foo"));