Bug 589025 - Support content-disposition attribute in e10s external app handling, r=dwitte, blocking-fennec2.0b1=blassey
authorBrian Crowder <crowder@fiverocks.com>
Mon, 13 Sep 2010 11:17:00 -0700
changeset 53715 4906e07c0970aa429c19e0c15b4b26eb17f7e216
parent 53714 7060ac6871d161c7afca3fb770a561952d752fb6
child 53716 a2d78881240cfbc09dbebde875f8527a729012ae
push idunknown
push userunknown
push dateunknown
reviewersdwitte
bugs589025
milestone2.0b6pre
Bug 589025 - Support content-disposition attribute in e10s external app handling, r=dwitte, blocking-fennec2.0b1=blassey Bug 589025 - Support content-disposition attribute in e10s external app handling, r=dwitte, blocking-fennec2.0b1=blassey
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/ExternalHelperAppParent.h
uriloader/exthandler/nsExternalHelperAppService.cpp
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -116,17 +116,19 @@ parent:
 
     PContentPermissionRequest(nsCString aType, URI uri);
 
     PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
                    PRInt32[] aIntParams, nsString[] aStringParams);
 
     __delete__();
 
-    PExternalHelperApp(URI uri, nsCString aMimeContentType, bool aForceSave, PRInt64 aContentLength);
+    PExternalHelperApp(URI uri, nsCString aMimeContentType,
+                       nsCString aContentDisposition, bool aForceSave,
+                       PRInt64 aContentLength);
 
 child:
     CreateWidget(MagicWindowHandle parentWidget);
 
     LoadURL(nsCString uri);
 
     Move(PRUint32 x,
          PRUint32 y,
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1236,16 +1236,17 @@ TabChildGlobal::GetPrincipal()
   if (!mTabChild)
     return nsnull;
   return mTabChild->GetPrincipal();
 }
 
 PExternalHelperAppChild*
 TabChild::AllocPExternalHelperApp(const IPC::URI& uri,
                                   const nsCString& aMimeContentType,
+                                  const nsCString& aContentDisposition,
                                   const bool& aForceSave,
                                   const PRInt64& aContentLength)
 {
   ExternalHelperAppChild *child = new ExternalHelperAppChild();
   child->AddRef();
   return child;
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -222,16 +222,17 @@ public:
                                                      const nsCString&,
                                                      const nsCString&,
                                                      const nsTArray<int>&,
                                                      const nsTArray<nsString>&);
     virtual bool DeallocPContentDialog(PContentDialogChild* aDialog);
     virtual PExternalHelperAppChild *AllocPExternalHelperApp(
             const IPC::URI& uri,
             const nsCString& aMimeContentType,
+            const nsCString& aContentDisposition,
             const bool& aForceSave,
             const PRInt64& aContentLength);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppChild *aService);
     static void ParamsToArrays(nsIDialogParamBlock* aParams,
                                nsTArray<int>& aIntParams,
                                nsTArray<nsString>& aStringParams);
     static void ArraysToParams(const nsTArray<int>& aIntParams,
                                const nsTArray<nsString>& aStringParams,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -810,22 +810,23 @@ TabParent::GetFrameLoader() const
 {
   nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(mFrameElement);
   return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nsnull;
 }
 
 PExternalHelperAppParent*
 TabParent::AllocPExternalHelperApp(const IPC::URI& uri,
                                    const nsCString& aMimeContentType,
+                                   const nsCString& aContentDisposition,
                                    const bool& aForceSave,
                                    const PRInt64& aContentLength)
 {
   ExternalHelperAppParent *parent = new ExternalHelperAppParent(uri, aContentLength);
   parent->AddRef();
-  parent->Init(this, aMimeContentType, aForceSave);
+  parent->Init(this, aMimeContentType, aContentDisposition, aForceSave);
   return parent;
 }
 
 bool
 TabParent::DeallocPExternalHelperApp(PExternalHelperAppParent* aService)
 {
   ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
   parent->Release();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -145,16 +145,17 @@ public:
     {
       delete aDialog;
       return true;
     }
 
     virtual PExternalHelperAppParent* AllocPExternalHelperApp(
             const IPC::URI& uri,
             const nsCString& aMimeContentType,
+            const nsCString& aContentDisposition,
             const bool& aForceSave,
             const PRInt64& aContentLength);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppParent* aService);
 
     void LoadURL(nsIURI* aURI);
     void Move(PRUint32 x, PRUint32 y, PRUint32 width, PRUint32 height);
     void Activate();
     void SendMouseEvent(const nsAString& aType, float aX, float aY,
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -45,50 +45,53 @@
 #include "nsIBrowserDOMWindow.h"
 #include "nsStringStream.h"
 
 #include "mozilla/unused.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_ISUPPORTS_INHERITED3(ExternalHelperAppParent,
+NS_IMPL_ISUPPORTS_INHERITED4(ExternalHelperAppParent,
                              nsHashPropertyBag,
                              nsIRequest,
                              nsIChannel,
+                             nsIMultiPartChannel,
                              nsIResumableChannel)
 
 ExternalHelperAppParent::ExternalHelperAppParent(
     const IPC::URI& uri,
     const PRInt64& aContentLength)
   : mURI(uri)
   , mPending(PR_FALSE)
   , mLoadFlags(0)
   , mStatus(NS_OK)
   , mContentLength(aContentLength)
 {
 }
 
 void
 ExternalHelperAppParent::Init(TabParent *parent,
                               const nsCString& aMimeContentType,
+                              const nsCString& aContentDisposition,
                               const PRBool& aForceSave)
 {
   nsHashPropertyBag::Init();
 
   NS_ASSERTION(parent, "must have a non-null TabParent");
   nsCOMPtr<nsIContent> frame = do_QueryInterface(parent->GetOwnerElement());
   nsCOMPtr<nsISupports> container = frame->GetOwnerDoc()->GetContainer();
   nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(container);
 
   nsCOMPtr<nsIExternalHelperAppService> helperAppService =
     do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
   NS_ASSERTION(helperAppService, "No Helper App Service!");
 
   SetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, mContentLength);
+  SetContentDisposition(aContentDisposition);
   helperAppService->DoContent(aMimeContentType, this, ir,
                               aForceSave, getter_AddRefs(mListener));
 }
 
 bool
 ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID)
 {
   mEntityID = entityID;
@@ -326,10 +329,46 @@ ExternalHelperAppParent::ResumeAt(PRUint
 
 NS_IMETHODIMP
 ExternalHelperAppParent::GetEntityID(nsACString& aEntityID)
 {
   aEntityID = mEntityID;
   return NS_OK;
 }
 
+//
+// nsIMultiPartChannel implementation
+//
+
+NS_IMETHODIMP
+ExternalHelperAppParent::GetBaseChannel(nsIChannel* *aChannel)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+ExternalHelperAppParent::GetContentDisposition(nsACString& aContentDisposition)
+{
+  aContentDisposition = mContentDisposition;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ExternalHelperAppParent::SetContentDisposition(const nsACString& aDisposition)
+{
+  mContentDisposition = aDisposition;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ExternalHelperAppParent::GetPartID(PRUint32* aPartID)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+ExternalHelperAppParent::GetIsLastPart(PRBool* aIsLastPart)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -33,54 +33,58 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/PExternalHelperAppParent.h"
 #include "nsIChannel.h"
-#include "nsICancelable.h"
+#include "nsIMultiPartChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsHashPropertyBag.h"
 
 namespace IPC {
 class URI;
 }
 
 namespace mozilla {
 namespace dom {
 
 class TabParent;
 
 class ExternalHelperAppParent : public PExternalHelperAppParent
                               , public nsHashPropertyBag
                               , public nsIChannel
+                              , public nsIMultiPartChannel
                               , public nsIResumableChannel
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUEST
     NS_DECL_NSICHANNEL
+    NS_DECL_NSIMULTIPARTCHANNEL
     NS_DECL_NSIRESUMABLECHANNEL
 
     bool RecvOnStartRequest(const nsCString& entityID);
     bool RecvOnDataAvailable(const nsCString& data, const PRUint32& offset, const PRUint32& count);
     bool RecvOnStopRequest(const nsresult& code);
     
     ExternalHelperAppParent(const IPC::URI& uri, const PRInt64& contentLength);
     void Init(TabParent *parent,
               const nsCString& aMimeContentType,
+              const nsCString& aContentDisposition,
               const PRBool& aForceSave);
     virtual ~ExternalHelperAppParent();
 
 private:
   nsCOMPtr<nsIStreamListener> mListener;
   nsCOMPtr<nsIURI> mURI;
   PRBool mPending;
   nsLoadFlags mLoadFlags;
   nsresult mStatus;
   PRInt64 mContentLength;
+  nsCString mContentDisposition;
   nsCString mEntityID;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -694,26 +694,31 @@ NS_IMETHODIMP nsExternalHelperAppService
     nsCOMPtr<nsIDocShellTreeOwner> owner;
     item->GetTreeOwner(getter_AddRefs(owner));
     NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
     if (!tabchild)
       return NS_ERROR_FAILURE;
 
+    nsCString disp;
+    if (channel)
+      ExtractDisposition(channel, disp);
+
     // 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.
     using mozilla::dom::TabChild;
     using mozilla::dom::ExternalHelperAppChild;
     TabChild *child = static_cast<TabChild*>(tabchild.get());
     mozilla::dom::PExternalHelperAppChild *pc;
     pc = child->SendPExternalHelperAppConstructor(IPC::URI(uri),
                                                   nsCString(aMimeContentType),
+                                                  disp,
                                                   aForceSave, contentLength);
     ExternalHelperAppChild *childListener = static_cast<ExternalHelperAppChild *>(pc);
 
     NS_ADDREF(*aStreamListener = childListener);
 
     // FIXME:  Eventually we'll use this original listener to finish up client-side
     // work, such as closing a no-longer-needed window.  (Bug 588255)
     // nsExternalAppHandler * handler = new nsExternalAppHandler(nsnull,