Bug 1303727 - Propagate whether we're dealing with a local file to the parent. r=jduell draft
authorBlake Kaplan <mrbkap@gmail.com>
Tue, 10 Jan 2017 17:49:16 -0800
changeset 463710 dea3d9f609725e4c627915a0c57356484448f328
parent 463681 a3978751f45108ff1ae002ecebdc0fa23fc52b84
child 542759 9abb029e8a25f8697367e0220b1a60b0f3e3e425
push id42157
push userbmo:mrbkap@mozilla.com
push dateThu, 19 Jan 2017 17:42:40 +0000
reviewersjduell
bugs1303727
milestone53.0a1
Bug 1303727 - Propagate whether we're dealing with a local file to the parent. r=jduell MozReview-Commit-ID: GSx2WgNKN4T
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/ExternalHelperAppParent.h
uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1901,16 +1901,17 @@ ContentChild::DeallocPPSMContentDownload
 PExternalHelperAppChild*
 ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri,
                                            const nsCString& aMimeContentType,
                                            const nsCString& aContentDisposition,
                                            const uint32_t& aContentDispositionHint,
                                            const nsString& aContentDispositionFilename,
                                            const bool& aForceSave,
                                            const int64_t& aContentLength,
+                                           const bool& aWasFileChannel,
                                            const OptionalURIParams& aReferrer,
                                            PBrowserChild* aBrowser)
 {
   auto *child = new ExternalHelperAppChild();
   child->AddRef();
   return child;
 }
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -303,16 +303,17 @@ public:
   virtual PExternalHelperAppChild*
   AllocPExternalHelperAppChild(const OptionalURIParams& uri,
                                const nsCString& aMimeContentType,
                                const nsCString& aContentDisposition,
                                const uint32_t& aContentDispositionHint,
                                const nsString& aContentDispositionFilename,
                                const bool& aForceSave,
                                const int64_t& aContentLength,
+                               const bool& aWasFileChannel,
                                const OptionalURIParams& aReferrer,
                                PBrowserChild* aBrowser) override;
 
   virtual bool
   DeallocPExternalHelperAppChild(PExternalHelperAppChild *aService) override;
 
   virtual PHandlerServiceChild* AllocPHandlerServiceChild() override;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2974,20 +2974,22 @@ ContentParent::DeallocPPSMContentDownloa
 PExternalHelperAppParent*
 ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
                                              const nsCString& aMimeContentType,
                                              const nsCString& aContentDisposition,
                                              const uint32_t& aContentDispositionHint,
                                              const nsString& aContentDispositionFilename,
                                              const bool& aForceSave,
                                              const int64_t& aContentLength,
+                                             const bool& aWasFileChannel,
                                              const OptionalURIParams& aReferrer,
                                              PBrowserParent* aBrowser)
 {
-  ExternalHelperAppParent *parent = new ExternalHelperAppParent(uri, aContentLength);
+  ExternalHelperAppParent *parent =
+    new ExternalHelperAppParent(uri, aContentLength, aWasFileChannel);
   parent->AddRef();
   parent->Init(this,
                aMimeContentType,
                aContentDisposition,
                aContentDispositionHint,
                aContentDispositionFilename,
                aForceSave,
                aReferrer,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -821,16 +821,17 @@ private:
   virtual PExternalHelperAppParent*
   AllocPExternalHelperAppParent(const OptionalURIParams& aUri,
                                 const nsCString& aMimeContentType,
                                 const nsCString& aContentDisposition,
                                 const uint32_t& aContentDispositionHint,
                                 const nsString& aContentDispositionFilename,
                                 const bool& aForceSave,
                                 const int64_t& aContentLength,
+                                const bool& aWasFileChannel,
                                 const OptionalURIParams& aReferrer,
                                 PBrowserParent* aBrowser) override;
 
   virtual bool
   DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService) override;
 
   virtual PHandlerServiceParent* AllocPHandlerServiceParent() override;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -854,16 +854,17 @@ parent:
 
     async PExternalHelperApp(OptionalURIParams uri,
                              nsCString aMimeContentType,
                              nsCString aContentDisposition,
                              uint32_t aContentDispositionHint,
                              nsString aContentDispositionFilename,
                              bool aForceSave,
                              int64_t aContentLength,
+                             bool aWasFileChannel,
                              OptionalURIParams aReferrer,
                              nullable PBrowser aBrowser);
 
     async PHandlerService();
 
     async AddGeolocationListener(Principal principal, bool highAccuracy);
     async RemoveGeolocationListener();
     async SetGeolocationHigherAccuracy(bool enable);
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -29,30 +29,33 @@ namespace dom {
 
 NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent,
                             nsHashPropertyBag,
                             nsIRequest,
                             nsIChannel,
                             nsIMultiPartChannel,
                             nsIPrivateBrowsingChannel,
                             nsIResumableChannel,
-                            nsIStreamListener)
+                            nsIStreamListener,
+                            nsIExternalHelperAppParent)
 
 ExternalHelperAppParent::ExternalHelperAppParent(
     const OptionalURIParams& uri,
-    const int64_t& aContentLength)
+    const int64_t& aContentLength,
+    const bool& aWasFileChannel)
   : mURI(DeserializeURI(uri))
   , mPending(false)
 #ifdef DEBUG
   , mDiverted(false)
 #endif
   , mIPCClosed(false)
   , mLoadFlags(0)
   , mStatus(NS_OK)
   , mContentLength(aContentLength)
+  , mWasFileChannel(aWasFileChannel)
 {
 }
 
 void
 ExternalHelperAppParent::Init(ContentParent *parent,
                               const nsCString& aMimeContentType,
                               const nsCString& aContentDispositionHeader,
                               const uint32_t& aContentDispositionHint,
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -23,26 +23,44 @@ class OptionalURIParams;
 } // namespace ipc
 
 namespace net {
 class PChannelDiverterParent;
 } // namespace net
 
 namespace dom {
 
+#define NS_IEXTERNALHELPERAPPPARENT_IID \
+{ 0x127a01bc, 0x2a49, 0x46a8, \
+  { 0x8c, 0x63, 0x4b, 0x5d, 0x3c, 0xa4, 0x07, 0x9c } }
+
+class nsIExternalHelperAppParent : public nsISupports
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEXTERNALHELPERAPPPARENT_IID)
+
+  /**
+   * Returns true if this fake channel represented a file channel in the child.
+   */
+  virtual bool WasFileChannel() = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIExternalHelperAppParent, NS_IEXTERNALHELPERAPPPARENT_IID)
+
 class ContentParent;
 class PBrowserParent;
 
 class ExternalHelperAppParent : public PExternalHelperAppParent
                               , public nsHashPropertyBag
                               , public nsIChannel
                               , public nsIMultiPartChannel
                               , public nsIResumableChannel
                               , public nsIStreamListener
                               , public net::PrivateBrowsingChannel<ExternalHelperAppParent>
+                              , public nsIExternalHelperAppParent
 {
     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
 
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIREQUEST
     NS_DECL_NSICHANNEL
     NS_DECL_NSIMULTIPARTCHANNEL
@@ -53,17 +71,22 @@ public:
     mozilla::ipc::IPCResult RecvOnStartRequest(const nsCString& entityID) override;
     mozilla::ipc::IPCResult RecvOnDataAvailable(const nsCString& data,
                                                 const uint64_t& offset,
                                                 const uint32_t& count) override;
     mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& code) override;
 
     mozilla::ipc::IPCResult RecvDivertToParentUsing(PChannelDiverterParent* diverter) override;
 
-    ExternalHelperAppParent(const OptionalURIParams& uri, const int64_t& contentLength);
+    bool WasFileChannel() override {
+      return mWasFileChannel;
+    }
+
+    ExternalHelperAppParent(const OptionalURIParams& uri, const int64_t& contentLength,
+                            const bool& wasFileChannel);
     void Init(ContentParent *parent,
               const nsCString& aMimeContentType,
               const nsCString& aContentDisposition,
               const uint32_t& aContentDispositionHint,
               const nsString& aContentDispositionFilename,
               const bool& aForceSave,
               const OptionalURIParams& aReferrer,
               PBrowserParent* aBrowser);
@@ -80,16 +103,17 @@ private:
   bool mPending;
 #ifdef DEBUG
   bool mDiverted;
 #endif
   bool mIPCClosed;
   nsLoadFlags mLoadFlags;
   nsresult mStatus;
   int64_t mContentLength;
+  bool mWasFileChannel;
   uint32_t mContentDisposition;
   nsString mContentDispositionFilename;
   nsCString mContentDispositionHeader;
   nsCString mEntityID;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -700,45 +700,51 @@ nsExternalHelperAppService::DoContentCon
   ContentChild *child = ContentChild::GetSingleton();
   if (!child) {
     return NS_ERROR_FAILURE;
   }
 
   nsCString disp;
   nsCOMPtr<nsIURI> uri;
   int64_t contentLength = -1;
+  bool wasFileChannel = false;
   uint32_t contentDisposition = -1;
   nsAutoString fileName;
 
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   if (channel) {
     channel->GetURI(getter_AddRefs(uri));
     channel->GetContentLength(&contentLength);
     channel->GetContentDisposition(&contentDisposition);
     channel->GetContentDispositionFilename(fileName);
     channel->GetContentDispositionHeader(disp);
+
+    nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(aRequest));
+    wasFileChannel = fileChan != nullptr;
   }
 
+
   nsCOMPtr<nsIURI> referrer;
   NS_GetReferrerFromChannel(channel, getter_AddRefs(referrer));
 
   OptionalURIParams uriParams, referrerParams;
   SerializeURI(uri, uriParams);
   SerializeURI(referrer, referrerParams);
 
   // Now we build a protocol for forwarding our data to the parent.  The
   // protocol will act as a listener on the child-side and create a "real"
   // helperAppService listener on the parent-side, via another call to
   // DoContent.
   mozilla::dom::PExternalHelperAppChild *pc =
     child->SendPExternalHelperAppConstructor(uriParams,
                                               nsCString(aMimeContentType),
                                               disp, contentDisposition,
-                                              fileName, aForceSave, 
-                                              contentLength, referrerParams,
+                                              fileName, aForceSave,
+                                              contentLength, wasFileChannel,
+                                              referrerParams,
                                               mozilla::dom::TabChild::GetFrom(window));
   ExternalHelperAppChild *childListener = static_cast<ExternalHelperAppChild *>(pc);
 
   NS_ADDREF(*aStreamListener = childListener);
 
   uint32_t reason = nsIHelperAppLauncherDialog::REASON_CANTHANDLE;
 
   RefPtr<nsExternalAppHandler> handler =
@@ -1622,21 +1628,28 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
 
   // Set mTimeDownloadStarted here as the download has already started and
   // we want to record the start time before showing the filepicker.
   mTimeDownloadStarted = PR_Now();
 
   mRequest = request;
 
   nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request);
-  
+
   nsresult rv;
-  
+
   nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(request));
   mIsFileChannel = fileChan != nullptr;
+  if (!mIsFileChannel) {
+    // It's possible that this request came from the child process and the
+    // file channel actually lives there. If this returns true, then our
+    // mSourceUrl will be an nsIFileURL anyway.
+    nsCOMPtr<dom::nsIExternalHelperAppParent> parent(do_QueryInterface(request));
+    mIsFileChannel = parent && parent->WasFileChannel();
+  }
 
   // Get content length
   if (aChannel) {
     aChannel->GetContentLength(&mContentLength);
   }
 
   nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(request, &rv));
   // Determine whether a new window was opened specifically for this request