Bug 1434163 - Make all nsIURI attributes readonly draft
authorValentin Gosu <valentin.gosu@gmail.com>
Tue, 27 Feb 2018 00:07:48 +0100
changeset 762724 5887820248a9d3d954ed5bb68e41e8bb53acb274
parent 762567 9caf14e0b300424d05fe5dd5afa7b9d1c65a5416
child 763030 b74dbbca74864958b4e105a94f46005d074e6b2e
push id101244
push uservalentin.gosu@gmail.com
push dateFri, 02 Mar 2018 22:15:00 +0000
bugs1434163
milestone60.0a1
Bug 1434163 - Make all nsIURI attributes readonly 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"));