Bug 1442242 - Add nsIURIMutator method to mark when the URI implementation should support nsIFileURL r=mayhemer
authorValentin Gosu <valentin.gosu@gmail.com>
Tue, 20 Mar 2018 12:52:43 +0100
changeset 409111 12eb3cffb3a54b84c19ef380e819c01bc0a65dcb
parent 409110 f11c1c4efc86f78cc95eaf5d221e91018e893623
child 409112 60b94194d25cef664bf63bb8a7cc514d3835a1a7
push id33675
push usertoros@mozilla.com
push dateWed, 21 Mar 2018 09:40:24 +0000
treeherdermozilla-central@f4ddf30ecf57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1442242
milestone61.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 1442242 - Add nsIURIMutator method to mark when the URI implementation should support nsIFileURL r=mayhemer * This is needed in order to make the constructors of URI implementations private MozReview-Commit-ID: 8dddDXbmrfF
netwerk/base/nsIFileURL.idl
netwerk/base/nsIURIMutator.idl
netwerk/base/nsStandardURL.h
netwerk/protocol/file/nsFileProtocolHandler.cpp
netwerk/protocol/res/SubstitutingProtocolHandler.h
--- a/netwerk/base/nsIFileURL.idl
+++ b/netwerk/base/nsIFileURL.idl
@@ -25,13 +25,18 @@ interface nsIFileURL : nsIURL
      */
     readonly attribute nsIFile file;
 };
 
 [scriptable, builtinclass, uuid(a588b6f2-d2b9-4024-84c7-be3368546b57)]
 interface nsIFileURLMutator : nsISupports
 {
     /*
+     *  - Marks the inner URI implementation as one that supports nsIFileURL.
+     */
+    [must_use, noscript] void markFileURL();
+
+    /*
      *  - Setter clones the nsIFile object (allowing the caller to safely modify
      *    the nsIFile object after setting it on this interface).
      */
     [must_use, noscript] void setFile(in nsIFile aFile);
 };
--- a/netwerk/base/nsIURIMutator.idl
+++ b/netwerk/base/nsIURIMutator.idl
@@ -27,58 +27,63 @@ class URIParams;
 
 template <class T>
 class BaseURIMutator
 {
 // This is the base class that can be extended by implementors of nsIURIMutator
 // in order to avoid code duplication
 // Class type T should be the type of the class that implements nsIURI
 protected:
+  virtual T* Create()
+  {
+    return new T();
+  }
+
   MOZ_MUST_USE nsresult InitFromURI(T* aURI)
   {
     nsCOMPtr<nsIURI> clone;
     nsresult rv = aURI->Clone(getter_AddRefs(clone));
     if (NS_FAILED(rv)) {
       return rv;
     }
     mURI = static_cast<T*>(clone.get());
     return NS_OK;
   }
 
   MOZ_MUST_USE nsresult InitFromInputStream(nsIObjectInputStream* aStream)
   {
-    RefPtr<T> uri = new T();
+    RefPtr<T> uri = Create();
     nsresult rv = uri->ReadPrivate(aStream);
     if (NS_FAILED(rv)) {
       return rv;
     }
     mURI = uri.forget();
     return NS_OK;
   }
 
   MOZ_MUST_USE nsresult InitFromIPCParams(const mozilla::ipc::URIParams& aParams)
   {
-    RefPtr<T> uri = new T();
+    RefPtr<T> uri = Create();
     bool ret = uri->Deserialize(aParams);
     if (!ret) {
       return NS_ERROR_FAILURE;
     }
     mURI = uri.forget();
     return NS_OK;
   }
 
   MOZ_MUST_USE nsresult InitFromSpec(const nsACString& aSpec)
   {
     nsresult rv = NS_OK;
     RefPtr<T> uri;
     if (mURI) {
       // This only works because all other Init methods create a new object
       mURI.swap(uri);
     } else {
-      uri = new T();
+      uri = Create();
     }
 
     rv = uri->SetSpecInternal(aSpec);
     if (NS_FAILED(rv)) {
       return rv;
     }
     mURI = uri.forget();
     return NS_OK;
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -397,17 +397,17 @@ public:
                 nsCOMPtr<nsIURIMutator> mutator = this;
                 mutator.forget(aMutator);
             }
             RefPtr<T> uri;
             if (BaseURIMutator<T>::mURI) {
                 // We don't need a new URI object if we already have one
                 BaseURIMutator<T>::mURI.swap(uri);
             } else {
-                uri = new T();
+                uri = Create();
             }
             nsresult rv = uri->Init(aURLType, aDefaultPort, aSpec, aCharset, aBaseURI);
             if (NS_FAILED(rv)) {
                 return rv;
             }
             BaseURIMutator<T>::mURI = uri.forget();
             return NS_OK;
         }
@@ -459,16 +459,28 @@ public:
             }
             if (aMutator) {
                 nsCOMPtr<nsIURIMutator> mutator = this;
                 mutator.forget(aMutator);
             }
             return BaseURIMutator<T>::mURI->SetFileExtensionInternal(aFileExtension);
         }
 
+        T* Create() override
+        {
+            return new T(mMarkedFileURL);
+        }
+
+        MOZ_MUST_USE NS_IMETHOD
+        MarkFileURL() override
+        {
+            mMarkedFileURL = true;
+            return NS_OK;
+        }
+
         MOZ_MUST_USE NS_IMETHOD
         SetFile(nsIFile* aFile) override
         {
             RefPtr<T> uri;
             if (BaseURIMutator<T>::mURI) {
                 // We don't need a new URI object if we already have one
                 BaseURIMutator<T>::mURI.swap(uri);
             } else {
@@ -482,16 +494,18 @@ public:
             BaseURIMutator<T>::mURI.swap(uri);
             return NS_OK;
         }
 
         explicit TemplatedMutator() { }
     private:
         virtual ~TemplatedMutator() { }
 
+        bool mMarkedFileURL = false;
+
         friend T;
     };
 
     class Mutator final
         : public TemplatedMutator<nsStandardURL>
     {
         NS_DECL_ISUPPORTS
     public:
--- a/netwerk/protocol/file/nsFileProtocolHandler.cpp
+++ b/netwerk/protocol/file/nsFileProtocolHandler.cpp
@@ -162,28 +162,27 @@ nsFileProtocolHandler::GetProtocolFlags(
 }
 
 NS_IMETHODIMP
 nsFileProtocolHandler::NewURI(const nsACString &spec,
                               const char *charset,
                               nsIURI *aBaseURI,
                               nsIURI **result)
 {
-    nsCOMPtr<nsIURI> url = new nsStandardURL(true);
-
     nsAutoCString buf(spec);
 #if defined(XP_WIN)
     buf.Truncate();
     if (!net_NormalizeFileURL(spec, buf)) {
         buf = spec;
     }
 #endif
 
     nsCOMPtr<nsIURI> base(aBaseURI);
-    return NS_MutateURI(url)
+    return NS_MutateURI(new nsStandardURL::Mutator())
+      .Apply(NS_MutatorMethod(&nsIFileURLMutator::MarkFileURL))
       .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
                               nsIStandardURL::URLTYPE_NO_AUTHORITY,
                               -1, buf, charset, base, nullptr))
       .Finalize(result);
 }
 
 NS_IMETHODIMP
 nsFileProtocolHandler::NewChannel2(nsIURI* uri,
@@ -252,22 +251,17 @@ nsFileProtocolHandler::NewFileURI(nsIFil
 }
 
 NS_IMETHODIMP
 nsFileProtocolHandler::NewFileURIMutator(nsIFile *aFile, nsIURIMutator **aResult)
 {
     NS_ENSURE_ARG_POINTER(aFile);
     nsresult rv;
 
-    nsCOMPtr<nsIURI> url = new nsStandardURL(true);
-    nsCOMPtr<nsIURIMutator> mutator;
-    rv = url->Mutate(getter_AddRefs(mutator));
-    if (NS_FAILED(rv)) {
-        return rv;
-    }
+    nsCOMPtr<nsIURIMutator> mutator = new nsStandardURL::Mutator();
     nsCOMPtr<nsIFileURLMutator> fileMutator = do_QueryInterface(mutator, &rv);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     // NOTE: the origin charset is assigned the value of the platform
     // charset by the SetFile method.
     rv = fileMutator->SetFile(aFile);
--- a/netwerk/protocol/res/SubstitutingProtocolHandler.h
+++ b/netwerk/protocol/res/SubstitutingProtocolHandler.h
@@ -131,16 +131,21 @@ public:
   class Mutator
     : public TemplatedMutator<SubstitutingURL>
   {
     NS_DECL_ISUPPORTS
   public:
     explicit Mutator() = default;
   private:
     virtual ~Mutator() = default;
+
+    SubstitutingURL* Create() override
+    {
+      return new SubstitutingURL();
+    }
   };
 
   NS_IMETHOD Mutate(nsIURIMutator** aMutator) override
   {
     RefPtr<SubstitutingURL::Mutator> mutator = new SubstitutingURL::Mutator();
     nsresult rv = mutator->InitFromURI(this);
     if (NS_FAILED(rv)) {
       return rv;