Bug 1334550 - Proxy moz-extension protocol requests to the parent process draft
authorHaik Aftandilian <haftandilian@mozilla.com>
Tue, 14 Feb 2017 12:33:17 -0800
changeset 490173 cb90a87b35efa72606608223240f336feeeb8d47
parent 490172 8fe108ba8707514a584434e2085580fa6dd201a3
child 490174 769987a1a7ebd8e3600ef11584cf61c34a0d4b28
push id47029
push userhaftandilian@mozilla.com
push dateMon, 27 Feb 2017 20:23:07 +0000
bugs1334550
milestone54.0a1
Bug 1334550 - Proxy moz-extension protocol requests to the parent process MozReview-Commit-ID: KqM6SuHtZud
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/protocol/file/ExtensionChannelChild.cpp
netwerk/protocol/file/ExtensionChannelChild.h
netwerk/protocol/file/ExtensionChannelParent.cpp
netwerk/protocol/file/ExtensionChannelParent.h
netwerk/protocol/file/PExtensionChannel.ipdl
netwerk/protocol/file/moz.build
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -206,16 +206,30 @@ NeckoChild::AllocPDataChannelChild(const
 
 bool
 NeckoChild::DeallocPDataChannelChild(PDataChannelChild* child)
 {
   // NB: See DataChannelChild::ActorDestroy.
   return true;
 }
 
+PExtensionChannelChild*
+NeckoChild::AllocPExtensionChannelChild(const URIParams& uri)
+{
+  // We don't allocate here: see ExtensionChannelChild::AsyncOpen()
+  MOZ_CRASH("AllocPFileChannelChild should not be called");
+  return nullptr;
+}
+
+bool
+NeckoChild::DeallocPExtensionChannelChild(PExtensionChannelChild* channel)
+{
+  return true;
+}
+
 PRtspControllerChild*
 NeckoChild::AllocPRtspControllerChild()
 {
   NS_NOTREACHED("AllocPRtspController should not be called");
   return nullptr;
 }
 
 bool
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -37,16 +37,20 @@ protected:
   virtual bool DeallocPCookieServiceChild(PCookieServiceChild*) override;
   virtual PWyciwygChannelChild* AllocPWyciwygChannelChild() override;
   virtual bool DeallocPWyciwygChannelChild(PWyciwygChannelChild*) override;
   virtual PFTPChannelChild*
     AllocPFTPChannelChild(const PBrowserOrId& aBrowser,
                           const SerializedLoadContext& aSerialized,
                           const FTPChannelCreationArgs& aOpenArgs) override;
   virtual bool DeallocPFTPChannelChild(PFTPChannelChild*) override;
+
+  virtual PExtensionChannelChild* AllocPExtensionChannelChild(const URIParams& uri) override;
+  virtual bool DeallocPExtensionChannelChild(PExtensionChannelChild* channel) override;
+
   virtual PWebSocketChild*
     AllocPWebSocketChild(const PBrowserOrId&,
                          const SerializedLoadContext&,
                          const uint32_t&) override;
   virtual bool DeallocPWebSocketChild(PWebSocketChild*) override;
   virtual PTCPSocketChild* AllocPTCPSocketChild(const nsString& host,
                                                 const uint16_t& port) override;
   virtual bool DeallocPTCPSocketChild(PTCPSocketChild*) override;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/net/HttpChannelParent.h"
 #include "mozilla/net/CookieServiceParent.h"
 #include "mozilla/net/WyciwygChannelParent.h"
 #include "mozilla/net/FTPChannelParent.h"
 #include "mozilla/net/WebSocketChannelParent.h"
 #include "mozilla/net/WebSocketEventListenerParent.h"
 #include "mozilla/net/DataChannelParent.h"
+#include "mozilla/net/ExtensionChannelParent.h"
 #include "mozilla/net/AltDataOutputStreamParent.h"
 #include "mozilla/Unused.h"
 #ifdef NECKO_PROTOCOL_rtsp
 #include "mozilla/net/RtspControllerParent.h"
 #include "mozilla/net/RtspChannelParent.h"
 #endif
 #include "mozilla/net/DNSRequestParent.h"
 #include "mozilla/net/ChannelDiverterParent.h"
@@ -484,16 +485,30 @@ NeckoParent::AllocPDataChannelParent(con
 
 bool
 NeckoParent::DeallocPDataChannelParent(PDataChannelParent* actor)
 {
   RefPtr<DataChannelParent> p = dont_AddRef(static_cast<DataChannelParent*>(actor));
   return true;
 }
 
+PExtensionChannelParent*
+NeckoParent::AllocPExtensionChannelParent(const URIParams& uri)
+{
+  RefPtr<ExtensionChannelParent> p = new ExtensionChannelParent(uri);
+  return p.forget().take();
+}
+
+bool
+NeckoParent::DeallocPExtensionChannelParent(PExtensionChannelParent* actor)
+{
+  RefPtr<ExtensionChannelParent> p = dont_AddRef(static_cast<ExtensionChannelParent*>(actor));
+  return true;
+}
+
 mozilla::ipc::IPCResult
 NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor,
                                          const uint32_t& channelId)
 {
   DataChannelParent* p = static_cast<DataChannelParent*>(actor);
   DebugOnly<bool> rv = p->Init(channelId);
   MOZ_ASSERT(rv);
   return IPC_OK();
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -166,16 +166,20 @@ protected:
   virtual PWebSocketEventListenerParent*
     AllocPWebSocketEventListenerParent(const uint64_t& aInnerWindowID) override;
   virtual bool DeallocPWebSocketEventListenerParent(PWebSocketEventListenerParent*) override;
 
   virtual PDataChannelParent*
     AllocPDataChannelParent(const uint32_t& channelId) override;
   virtual bool DeallocPDataChannelParent(PDataChannelParent* parent) override;
 
+  virtual PExtensionChannelParent*
+    AllocPExtensionChannelParent(const URIParams& uri) override;
+  virtual bool DeallocPExtensionChannelParent(PExtensionChannelParent* parent) override;
+
   virtual mozilla::ipc::IPCResult RecvPDataChannelConstructor(PDataChannelParent* aActor,
                                                               const uint32_t& channelId) override;
 
   virtual PRtspControllerParent* AllocPRtspControllerParent() override;
   virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) override;
 
   virtual PRtspChannelParent*
     AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -18,16 +18,17 @@ include protocol PTCPServerSocket;
 include protocol PUDPSocket;
 include protocol PDNSRequest;
 include protocol PChannelDiverter;
 include protocol PBlob; //FIXME: bug #792908
 include protocol PFileDescriptorSet;
 include protocol PDataChannel;
 include protocol PTransportProvider;
 include protocol PSendStream;
+include protocol PExtensionChannel;
 
 include protocol PRtspController;
 include protocol PRtspChannel;
 include URIParams;
 include InputStreamParams;
 include NeckoChannelParams;
 include PBrowserOrId;
 include protocol PAltDataOutputStream;
@@ -54,27 +55,29 @@ nested(upto inside_cpow) sync protocol P
   manages PUDPSocket;
   manages PDNSRequest;
   manages PDataChannel;
   manages PRtspController;
   manages PRtspChannel;
   manages PChannelDiverter;
   manages PTransportProvider;
   manages PAltDataOutputStream;
+  manages PExtensionChannel;
 
 parent:
   async __delete__();
 
   nested(inside_cpow) async PCookieService();
   async PHttpChannel(PBrowserOrId browser,
                      SerializedLoadContext loadContext,
                      HttpChannelCreationArgs args);
   async PWyciwygChannel();
   async PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
                     FTPChannelCreationArgs args);
+  async PExtensionChannel(URIParams uri);
 
   async PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext,
                    uint32_t aSerialID);
   async PTCPServerSocket(uint16_t localPort, uint16_t backlog, bool useArrayBuffers);
   async PUDPSocket(Principal principal, nsCString filter);
 
   async PDNSRequest(nsCString hostName, uint32_t flags, nsCString networkInterface);
 
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/file/ExtensionChannelChild.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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 "ExtensionChannelChild.h"
+
+#include "mozilla/Unused.h"
+#include "mozilla/net/NeckoChild.h"
+
+namespace mozilla {
+namespace net {
+
+NS_IMPL_ISUPPORTS_INHERITED(ExtensionChannelChild, nsBaseChannel, nsIChildChannel)
+
+ExtensionChannelChild::ExtensionChannelChild(nsIURI* aURI) : mIPCOpen(false)
+{
+    SetURI(aURI);
+}
+
+ExtensionChannelChild::~ExtensionChannelChild()
+{
+}
+
+NS_IMETHODIMP
+ExtensionChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
+                                        nsISupports *aContext)
+{
+    nsresult rv;
+    if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
+        MOZ_ASSERT(!aContext, "aContext should be null!");
+        rv = AsyncOpen2(aListener);
+    }
+    else {
+        rv = AsyncOpen(aListener, aContext);
+    }
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+    }
+
+    if (mIPCOpen) {
+        Unused << Send__delete__(this);
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+ExtensionChannelChild::ConnectParent(uint32_t Id)
+{
+    URIParams uriParams;
+    if (!gNeckoChild->SendPExtensionChannelConstructor(this, uriParams)) {
+        return NS_ERROR_FAILURE;
+    }
+    return NS_OK;
+}
+
+void
+ExtensionChannelChild::AddIPDLReference()
+{
+    AddRef();
+    mIPCOpen = true;
+}
+
+void
+ExtensionChannelChild::ActorDestroy(ActorDestroyReason why)
+{
+    MOZ_ASSERT(mIPCOpen);
+    mIPCOpen = false;
+    Release();
+}
+
+} // namespace net
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/file/ExtensionChannelChild.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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/. */
+
+#ifndef NS_EXTENSIONCHANNELCHILD_H
+#define NS_EXTENSIONCHANNELCHILD_H
+
+#include "nsBaseChannel.h"
+#include "nsIChildChannel.h"
+#include "nsISupportsImpl.h"
+
+#include "mozilla/net/PExtensionChannelChild.h"
+
+namespace mozilla {
+namespace net {
+
+class ExtensionChannelChild : public nsBaseChannel
+                            , public nsIChildChannel
+                            , public PExtensionChannelChild
+{
+public:
+    NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_NSICHILDCHANNEL
+
+    explicit ExtensionChannelChild(nsIURI *uri);
+
+protected:
+    virtual void ActorDestroy(ActorDestroyReason why) override;
+
+private:
+    ~ExtensionChannelChild();
+
+    void AddIPDLReference();
+
+    bool mIPCOpen;
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif /* NS_EXTENSIONCHANNELCHILD_H */
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/file/ExtensionChannelParent.cpp
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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 "ExtensionChannelParent.h"
+#include "mozilla/Assertions.h"
+#include "nsNetUtil.h"
+#include "nsIChannel.h"
+
+namespace mozilla {
+namespace net {
+
+NS_IMPL_ISUPPORTS(ExtensionChannelParent, nsIParentChannel)
+
+ExtensionChannelParent::ExtensionChannelParent(const URIParams& uri)
+{
+}
+
+ExtensionChannelParent::~ExtensionChannelParent()
+{
+}
+
+bool
+ExtensionChannelParent::Init(const URIParams &uri)
+{
+    return true;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::SetParentListener(HttpChannelParentListener* aListener)
+{
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::NotifyTrackingProtectionDisabled()
+{
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::NotifyTrackingResource()
+{
+    // Nothing to do.
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::Delete()
+{
+    // Nothing to do.
+    return NS_OK;
+}
+
+void
+ExtensionChannelParent::ActorDestroy(ActorDestroyReason why)
+{
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::OnStartRequest(nsIRequest *aRequest,
+                                       nsISupports *aContext)
+{
+    // We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
+    // the created nsFileChannel. We don't have anywhere to send the data in the
+    // parent, so abort the binding.
+    return NS_BINDING_ABORTED;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::OnStopRequest(nsIRequest *aRequest,
+                                      nsISupports *aContext,
+                                      nsresult aStatusCode)
+{
+    // See above.
+    MOZ_ASSERT(NS_FAILED(aStatusCode));
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+ExtensionChannelParent::OnDataAvailable(nsIRequest *aRequest,
+                                        nsISupports *aContext,
+                                        nsIInputStream *aInputStream,
+                                        uint64_t aOffset,
+                                        uint32_t aCount)
+{
+    // See above.
+    MOZ_CRASH("Should never be called");
+}
+
+} // namespace net
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/file/ExtensionChannelParent.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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/. */
+
+#ifndef NS_FILECHANNELPARENT_H
+#define NS_FILECHANNELPARENT_H
+
+#include "nsFileChannel.h"
+#include "nsIParentChannel.h"
+#include "nsISupportsImpl.h"
+
+#include "mozilla/net/PExtensionChannelParent.h"
+
+namespace mozilla {
+namespace net {
+
+class ExtensionChannelParent : public nsIParentChannel
+                             , public PExtensionChannelParent
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIPARENTCHANNEL
+    NS_DECL_NSIREQUESTOBSERVER
+    NS_DECL_NSISTREAMLISTENER
+
+    ExtensionChannelParent(const URIParams &uri);
+    MOZ_MUST_USE bool Init(const URIParams &uri);
+
+private:
+    ~ExtensionChannelParent();
+
+    virtual void ActorDestroy(ActorDestroyReason why) override;
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif /* NS_FILECHANNELPARENT_H */
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/file/PExtensionChannel.ipdl
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
+
+/* 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 protocol PNecko;
+include URIParams;
+
+namespace mozilla {
+namespace net {
+
+async protocol PExtensionChannel
+{
+  manager PNecko;
+
+parent:
+  // Note: channels are opened during construction, so no open method here:
+  // see PNecko.ipdl
+
+  async __delete__();
+};
+
+} // namespace net
+} // namespace mozilla
+
--- a/netwerk/protocol/file/moz.build
+++ b/netwerk/protocol/file/moz.build
@@ -3,31 +3,42 @@
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Networking: File')
 
 EXPORTS.mozilla.net += [
+    'ExtensionChannelChild.h',
+    'ExtensionChannelParent.h',
+    'nsFileChannel.h',
     'nsFileProtocolHandler.h',
 ]
 
 XPIDL_SOURCES += [
     'nsIFileChannel.idl',
     'nsIFileProtocolHandler.idl',
 ]
 
 XPIDL_MODULE = 'necko_file'
 
 UNIFIED_SOURCES += [
+    'ExtensionChannelChild.cpp',
+    'ExtensionChannelParent.cpp',
     'nsFileChannel.cpp',
     'nsFileProtocolHandler.cpp',
 ]
 
+IPDL_SOURCES += [
+    'PExtensionChannel.ipdl',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/netwerk/base',
 ]
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']