Bug 1351163: Part 3 - Don't open moz-extension: base channel on NewChannel2(). r=bz draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 06 Apr 2017 11:49:18 -0700
changeset 557410 5389cd8a42f8d10d9c505c40a15db362c065dfc1
parent 557409 4149737a37ac6030ba147aac22e107f34b99a1a4
child 557411 0c8a706ee7af855d4b8e1cce8a1ab3e87800061c
push id52705
push usermaglione.k@gmail.com
push dateThu, 06 Apr 2017 18:59:23 +0000
reviewersbz
bugs1351163
milestone55.0a1
Bug 1351163: Part 3 - Don't open moz-extension: base channel on NewChannel2(). r=bz MozReview-Commit-ID: F8H75VM33nz
netwerk/protocol/res/ExtensionProtocolHandler.cpp
--- a/netwerk/protocol/res/ExtensionProtocolHandler.cpp
+++ b/netwerk/protocol/res/ExtensionProtocolHandler.cpp
@@ -6,23 +6,21 @@
 
 #include "ExtensionProtocolHandler.h"
 
 #include "nsIAddonPolicyService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsIStreamListener.h"
-#include "nsIRequestObserver.h"
-#include "nsIInputStreamChannel.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsIStreamConverterService.h"
-#include "nsIPipe.h"
 #include "nsNetUtil.h"
+#include "nsSimpleChannel.h"
 #include "LoadInfo.h"
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_QUERY_INTERFACE(ExtensionProtocolHandler, nsISubstitutingProtocolHandler,
                         nsIProtocolHandler, nsIProtocolHandlerWithDynamicFlags,
                         nsISupportsWeakReference)
@@ -40,49 +38,16 @@ ExtensionProtocolHandler::GetFlagsForURI
     nsresult rv = aps->ExtensionURILoadableByAnyone(aURI, &loadableByAnyone);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   *aFlags = URI_STD | URI_IS_LOCAL_RESOURCE | (loadableByAnyone ? (URI_LOADABLE_BY_ANYONE | URI_FETCHABLE_BY_ANYONE) : URI_DANGEROUS_TO_LOAD);
   return NS_OK;
 }
 
-class PipeCloser : public nsIRequestObserver
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  explicit PipeCloser(nsIOutputStream* aOutputStream) :
-    mOutputStream(aOutputStream)
-  {
-  }
-
-  NS_IMETHOD OnStartRequest(nsIRequest*, nsISupports*) override
-  {
-    return NS_OK;
-  }
-
-  NS_IMETHOD OnStopRequest(nsIRequest*, nsISupports*, nsresult aStatusCode) override
-  {
-    NS_ENSURE_TRUE(mOutputStream, NS_ERROR_UNEXPECTED);
-
-    nsresult rv = mOutputStream->Close();
-    mOutputStream = nullptr;
-    return rv;
-  }
-
-protected:
-  virtual ~PipeCloser() {}
-
-private:
-  nsCOMPtr<nsIOutputStream> mOutputStream;
-};
-
-NS_IMPL_ISUPPORTS(PipeCloser, nsIRequestObserver)
-
 bool
 ExtensionProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
                                               const nsACString& aPath,
                                               const nsACString& aPathname,
                                               nsACString& aResult)
 {
   // Create special moz-extension:-pages such as moz-extension://foo/_blank.html
   // for all registered extensions. We can't just do this as a substitution
@@ -106,16 +71,27 @@ ExtensionProtocolHandler::ResolveSpecial
       MOZ_RELEASE_ASSERT(Substring(aResult, 0, 5).Equals("data:"));
       return true;
     }
   }
 
   return false;
 }
 
+static inline Result<Ok, nsresult>
+WrapNSResult(nsresult aRv)
+{
+  if (NS_FAILED(aRv)) {
+    return Err(aRv);
+  }
+  return Ok();
+}
+
+#define NS_TRY(expr) MOZ_TRY(WrapNSResult(expr))
+
 nsresult
 ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI,
                                             nsILoadInfo* aLoadInfo,
                                             nsIChannel** result)
 {
   nsresult rv;
   nsCOMPtr<nsIURL> url = do_QueryInterface(aURI, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -125,55 +101,50 @@ ExtensionProtocolHandler::SubstituteChan
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!ext.LowerCaseEqualsLiteral("css")) {
     return NS_OK;
   }
 
   // Filter CSS files to replace locale message tokens with localized strings.
 
-  nsCOMPtr<nsIStreamConverterService> convService =
-    do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIChannel> channel = NS_NewSimpleChannel(
+    aURI, aLoadInfo, *result,
+    [aLoadInfo] (nsIStreamListener* listener, nsIChannel* channel, nsIChannel* origChannel) -> RequestOrReason {
+      nsresult rv;
+      nsCOMPtr<nsIStreamConverterService> convService =
+        do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
+      NS_TRY(rv);
 
-  const char* kFromType = "application/vnd.mozilla.webext.unlocalized";
-  const char* kToType = "text/css";
+      nsCOMPtr<nsIURI> uri;
+      NS_TRY(channel->GetURI(getter_AddRefs(uri)));
 
-  nsCOMPtr<nsIInputStream> inputStream;
-  nsCOMPtr<nsIOutputStream> outputStream;
-  rv = NS_NewPipe(getter_AddRefs(inputStream), getter_AddRefs(outputStream),
-                  0, UINT32_MAX, true, false);
-  NS_ENSURE_SUCCESS(rv, rv);
+      const char* kFromType = "application/vnd.mozilla.webext.unlocalized";
+      const char* kToType = "text/css";
 
-  nsCOMPtr<nsIStreamListener> listener;
-  nsCOMPtr<nsIRequestObserver> observer = new PipeCloser(outputStream);
-  rv = NS_NewSimpleStreamListener(getter_AddRefs(listener), outputStream, observer);
-  NS_ENSURE_SUCCESS(rv, rv);
+      nsCOMPtr<nsIStreamListener> converter;
+      NS_TRY(convService->AsyncConvertData(kFromType, kToType, listener,
+                                        uri, getter_AddRefs(converter)));
+      if (aLoadInfo) {
+        NS_TRY(origChannel->AsyncOpen2(converter));
+      } else {
+        NS_TRY(origChannel->AsyncOpen(converter, nullptr));
+      }
 
-  nsCOMPtr<nsIStreamListener> converter;
-  rv = convService->AsyncConvertData(kFromType, kToType, listener,
-                                     aURI, getter_AddRefs(converter));
-  NS_ENSURE_SUCCESS(rv, rv);
+      return RequestOrReason(origChannel);
+    });
+  NS_ENSURE_TRUE(channel, NS_ERROR_OUT_OF_MEMORY);
 
   if (aLoadInfo) {
     nsCOMPtr<nsILoadInfo> loadInfo =
         static_cast<LoadInfo*>(aLoadInfo)->CloneForNewRequest();
-      (*result)->SetLoadInfo(loadInfo);
-
-    rv = (*result)->AsyncOpen2(converter);
-  } else {
-    rv = (*result)->AsyncOpen(converter, nullptr);
+    (*result)->SetLoadInfo(loadInfo);
   }
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), aURI, inputStream,
-                                        NS_LITERAL_CSTRING("text/css"),
-                                        NS_LITERAL_CSTRING("utf-8"),
-                                        aLoadInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
 
   channel.swap(*result);
+
   return NS_OK;
 }
 
+#undef NS_TRY
+
 } // namespace net
 } // namespace mozilla