Bug 536289 - Part 2: Make FTP work for fennec. r=jduell a=blocking-fennec
authorAlon Zakai <azakai>
Tue, 10 Aug 2010 14:47:00 -0400
changeset 56321 e63ac78f181e146cf4490ce5f51294696bc66049
parent 56320 f3a6cf176c00c28691db75d0b0fb8db9db5ff29f
child 56322 8d1aca43c54b59b7bca7e596d019d5f8620991ee
push id16483
push userdwitte@mozilla.com
push dateThu, 21 Oct 2010 18:37:32 +0000
treeherdermozilla-central@0434c3cf6279 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell, blocking-fennec
bugs536289
milestone2.0b8pre
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 536289 - Part 2: Make FTP work for fennec. r=jduell a=blocking-fennec
netwerk/base/src/nsBaseChannel.h
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoCommon.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/protocol/ftp/Makefile.in
netwerk/protocol/ftp/nsFTPChannel.h
netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
netwerk/protocol/ftp/nsFtpProtocolHandler.h
netwerk/protocol/http/HttpBaseChannel.h
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -276,27 +276,29 @@ private:
   };
   friend class RedirectRunnable;
 
   nsRefPtr<nsInputStreamPump>         mPump;
   nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
   nsCOMPtr<nsIProgressEventSink>      mProgressSink;
   nsCOMPtr<nsIURI>                    mOriginalURI;
   nsCOMPtr<nsIURI>                    mURI;
-  nsCOMPtr<nsILoadGroup>              mLoadGroup;
   nsCOMPtr<nsISupports>               mOwner;
   nsCOMPtr<nsISupports>               mSecurityInfo;
-  nsCOMPtr<nsIStreamListener>         mListener;
-  nsCOMPtr<nsISupports>               mListenerContext;
   nsCOMPtr<nsIChannel>                mRedirectChannel;
   nsCString                           mContentType;
   nsCString                           mContentCharset;
   PRUint32                            mLoadFlags;
-  nsresult                            mStatus;
   PRPackedBool                        mQueriedProgressSink;
   PRPackedBool                        mSynthProgressEvents;
   PRPackedBool                        mWasOpened;
   PRPackedBool                        mWaitingOnAsyncRedirect;
   PRPackedBool                        mOpenRedirectChannel;
   PRUint32                            mRedirectFlags;
+
+protected:
+  nsCOMPtr<nsILoadGroup>              mLoadGroup;
+  nsCOMPtr<nsIStreamListener>         mListener;
+  nsCOMPtr<nsISupports>               mListenerContext;
+  nsresult                            mStatus;
 };
 
 #endif // !nsBaseChannel_h__
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -40,16 +40,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHttp.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/net/HttpChannelChild.h"
 #include "mozilla/net/CookieServiceChild.h"
 #include "mozilla/net/WyciwygChannelChild.h"
+#include "mozilla/net/FTPChannelChild.h"
 
 namespace mozilla {
 namespace net {
 
 PNeckoChild *gNeckoChild = nsnull;
 
 // C++ file contents
 NeckoChild::NeckoChild()
@@ -107,16 +108,34 @@ NeckoChild::DeallocPHttpChannel(PHttpCha
 {
   NS_ABORT_IF_FALSE(IsNeckoChild(), "DeallocPHttpChannel called by non-child!");
 
   HttpChannelChild* child = static_cast<HttpChannelChild*>(channel);
   child->ReleaseIPDLReference();
   return true;
 }
 
+PFTPChannelChild*
+NeckoChild::AllocPFTPChannel()
+{
+  // We don't allocate here: see FTPChannelChild::AsyncOpen()
+  NS_RUNTIMEABORT("AllocPFTPChannel should not be called");
+  return nsnull;
+}
+
+bool
+NeckoChild::DeallocPFTPChannel(PFTPChannelChild* channel)
+{
+  NS_ABORT_IF_FALSE(IsNeckoChild(), "DeallocPFTPChannel called by non-child!");
+
+  FTPChannelChild* child = static_cast<FTPChannelChild*>(channel);
+  child->ReleaseIPDLReference();
+  return true;
+}
+
 PCookieServiceChild* 
 NeckoChild::AllocPCookieService()
 {
   // We don't allocate here: see nsCookieService::GetSingleton()
   NS_NOTREACHED("AllocPCookieService should not be called");
   return nsnull;
 }
 
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -60,16 +60,18 @@ public:
 
 protected:
   virtual PHttpChannelChild* AllocPHttpChannel(PBrowserChild* iframeEmbedding);
   virtual bool DeallocPHttpChannel(PHttpChannelChild*);
   virtual PCookieServiceChild* AllocPCookieService();
   virtual bool DeallocPCookieService(PCookieServiceChild*);
   virtual PWyciwygChannelChild* AllocPWyciwygChannel();
   virtual bool DeallocPWyciwygChannel(PWyciwygChannelChild*);
+  virtual PFTPChannelChild* AllocPFTPChannel();
+  virtual bool DeallocPFTPChannel(PFTPChannelChild*);
 };
 
 /**
  * Reference to the PNecko Child protocol.
  * Null if this is not a content process.
  */
 extern PNeckoChild *gNeckoChild;
 
--- a/netwerk/ipc/NeckoCommon.h
+++ b/netwerk/ipc/NeckoCommon.h
@@ -68,22 +68,30 @@
       msg.Append(" (set NECKO_ERRORS_ARE_FATAL=1 in your environment to "      \
                       "convert this warning into a fatal error.)");            \
       NS_WARNING(msg.get());                                                   \
     }                                                                          \
   } while (0)
 
 #define DROP_DEAD()                                                            \
   do {                                                                         \
-    nsPrintfCString msg(1000,"FATAL NECKO ERROR: '%s' UNIMPLEMENTED",          \
+    nsPrintfCString msg(1000,"NECKO ERROR: '%s' UNIMPLEMENTED",                \
                         __FUNCTION__);                                         \
     NECKO_MAYBE_ABORT(msg);                                                    \
     return NS_ERROR_NOT_IMPLEMENTED;                                           \
   } while (0)
 
+#define ENSURE_CALLED_BEFORE_ASYNC_OPEN()                                      \
+  if (mIsPending || mWasOpened) {                                              \
+    nsPrintfCString msg(1000, "'%s' called after AsyncOpen: %s +%d",           \
+                        __FUNCTION__, __FILE__, __LINE__);                     \
+    NECKO_MAYBE_ABORT(msg);                                                    \
+  }                                                                            \
+  NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);                           \
+  NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
 
 namespace mozilla {
 namespace net {
 
 inline bool 
 IsNeckoChild() 
 {
   static bool didCheck = false;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -38,16 +38,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHttp.h"
 #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 "nsHTMLDNSPrefetch.h"
 
 namespace mozilla {
 namespace net {
 
 // C++ file contents
 NeckoParent::NeckoParent()
@@ -69,16 +70,32 @@ NeckoParent::AllocPHttpChannel(PBrowserP
 bool 
 NeckoParent::DeallocPHttpChannel(PHttpChannelParent* channel)
 {
   HttpChannelParent *p = static_cast<HttpChannelParent *>(channel);
   p->Release();
   return true;
 }
 
+PFTPChannelParent*
+NeckoParent::AllocPFTPChannel()
+{
+  FTPChannelParent *p = new FTPChannelParent();
+  p->AddRef();
+  return p;
+}
+
+bool
+NeckoParent::DeallocPFTPChannel(PFTPChannelParent* channel)
+{
+  FTPChannelParent *p = static_cast<FTPChannelParent *>(channel);
+  p->Release();
+  return true;
+}
+
 PCookieServiceParent* 
 NeckoParent::AllocPCookieService()
 {
   return new CookieServiceParent();
 }
 
 bool 
 NeckoParent::DeallocPCookieService(PCookieServiceParent* cs)
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -57,16 +57,18 @@ public:
 
 protected:
   virtual PHttpChannelParent* AllocPHttpChannel(PBrowserParent* browser);
   virtual bool DeallocPHttpChannel(PHttpChannelParent*);
   virtual PCookieServiceParent* AllocPCookieService();
   virtual bool DeallocPCookieService(PCookieServiceParent*);
   virtual PWyciwygChannelParent* AllocPWyciwygChannel();
   virtual bool DeallocPWyciwygChannel(PWyciwygChannelParent*);
+  virtual PFTPChannelParent* AllocPFTPChannel();
+  virtual bool DeallocPFTPChannel(PFTPChannelParent*);
   virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
                                    const PRUint16& flags);
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_NeckoParent_h
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -38,34 +38,37 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 include protocol PContent;
 include protocol PHttpChannel;
 include protocol PCookieService;
 include protocol PBrowser;
 include protocol PWyciwygChannel;
+include protocol PFTPChannel;
 
 namespace mozilla {
 namespace net {
 
 
 //-------------------------------------------------------------------
 sync protocol PNecko
 {
   manager PContent;
   manages PHttpChannel;
   manages PCookieService;
   manages PWyciwygChannel;
+  manages PFTPChannel;
 
 parent:
   __delete__();
 
   PCookieService();
   PWyciwygChannel();
+  PFTPChannel();
 
   HTMLDNSPrefetch(nsString hostname, PRUint16 flags);
 
 both:
   PHttpChannel(nullable PBrowser browser);
 };
 
 
--- a/netwerk/protocol/ftp/Makefile.in
+++ b/netwerk/protocol/ftp/Makefile.in
@@ -51,35 +51,53 @@ GRE_MODULE     = 1
 FORCE_STATIC_LIB = 1
 
 EXPORTS = ftpCore.h
 
 XPIDLSRCS = \
   nsIFTPChannel.idl \
   $(NULL)
 
+ifdef MOZ_IPC
+EXPORTS_NAMESPACES = mozilla/net
+
+EXPORTS_mozilla/net += \
+  FTPChannelParent.h \
+  FTPChannelChild.h  \
+  $(NULL)
+endif
+
 CPPSRCS = \
   nsFtpProtocolHandler.cpp \
   nsFTPChannel.cpp \
   nsFtpConnectionThread.cpp \
   nsFtpControlConnection.cpp \
   $(NULL)
 
+ifdef MOZ_IPC
+CPPSRCS += \
+  FTPChannelParent.cpp \
+  FTPChannelChild.cpp \
+  $(NULL)
+endif
+
 # Use -g for Irix mipspro builds as workaround for bug 92099
 ifneq (,$(filter IRIX IRIX64,$(OS_ARCH)))
 ifndef GNU_CC
 MODULE_OPTIMIZE_FLAGS=-O -g
 endif
 endif
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../../base/src \
   -I$(topsrcdir)/xpcom/ds \
   $(NULL)
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(OS_ARCH),WINNT)
 ifndef MOZ_DEBUG
 ifndef NO_LOGGING
 DEFINES += -DFORCE_PR_LOG
 endif
 endif
--- a/netwerk/protocol/ftp/nsFTPChannel.h
+++ b/netwerk/protocol/ftp/nsFTPChannel.h
@@ -57,16 +57,17 @@
 #include "nsIStreamListener.h"
 #include "nsAutoLock.h"
 #include "nsIFTPChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsIProxyInfo.h"
 #include "nsIProxiedChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsHashPropertyBag.h"
+#include "nsFtpProtocolHandler.h"
 
 class nsFtpChannel : public nsBaseChannel,
                      public nsIFTPChannel,
                      public nsIUploadChannel,
                      public nsIResumableChannel,
                      public nsIProxiedChannel
 {
 public:
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
+++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
@@ -44,16 +44,22 @@
  * Modifications to Mozilla code or documentation
  * identified per MPL Section 3.3
  *
  * Date         Modified by     Description of modification
  * 03/27/2000   IBM Corp.       Added PR_CALLBACK for Optlink
  *                               use in OS2
  */
 
+#ifdef MOZ_IPC
+#include "mozilla/net/NeckoChild.h"
+#include "mozilla/net/FTPChannelChild.h"
+using namespace mozilla::net;
+#endif
+
 #include "nsFtpProtocolHandler.h"
 #include "nsFTPChannel.h"
 #include "nsIURL.h"
 #include "nsIStandardURL.h"
 #include "nsCRT.h"
 #include "nsIComponentManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -76,16 +82,17 @@
 //    set NSPR_LOG_MODULES=nsFtp:5
 //    set NSPR_LOG_FILE=nspr.log
 //
 // this enables PR_LOG_DEBUG level information and places all output in
 // the file nspr.log
 //
 PRLogModuleInfo* gFTPLog = nsnull;
 #endif
+#undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 //-----------------------------------------------------------------------------
 
 #define IDLE_TIMEOUT_PREF     "network.ftp.idleConnectionTimeout"
 #define IDLE_CONNECTION_LIMIT 8 /* TODO pref me */
 
 #define QOS_DATA_PREF         "network.ftp.data.qos"
@@ -123,16 +130,21 @@ NS_IMPL_THREADSAFE_ISUPPORTS4(nsFtpProto
                               nsIProtocolHandler,
                               nsIProxiedProtocolHandler,
                               nsIObserver,
                               nsISupportsWeakReference)
 
 nsresult
 nsFtpProtocolHandler::Init()
 {
+#ifdef MOZ_IPC
+    if (IsNeckoChild())
+        NeckoChild::InitNeckoChild();
+#endif // MOZ_IPC
+
     if (mIdleTimeout == -1) {
         nsresult rv;
         nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
         if (NS_FAILED(rv)) return rv;
 
         rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &mIdleTimeout);
         if (NS_FAILED(rv))
             mIdleTimeout = 5*60; // 5 minute default
@@ -236,28 +248,30 @@ nsFtpProtocolHandler::NewChannel(nsIURI*
     return NewProxiedChannel(url, nsnull, result);
 }
 
 NS_IMETHODIMP
 nsFtpProtocolHandler::NewProxiedChannel(nsIURI* uri, nsIProxyInfo* proxyInfo,
                                         nsIChannel* *result)
 {
     NS_ENSURE_ARG_POINTER(uri);
-    nsFtpChannel *channel = new nsFtpChannel(uri, proxyInfo);
-    if (!channel)
-        return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(channel);
+    nsRefPtr<nsBaseChannel> channel;
+#ifdef MOZ_IPC
+    if (IsNeckoChild())
+        channel = new FTPChannelChild(uri);
+    else
+#endif
+        channel = new nsFtpChannel(uri, proxyInfo);
 
     nsresult rv = channel->Init();
     if (NS_FAILED(rv)) {
-        NS_RELEASE(channel);
         return rv;
     }
     
-    *result = channel;
+    channel.forget(result);
     return rv;
 }
 
 NS_IMETHODIMP 
 nsFtpProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
 {
     *_retval = (port == 21 || port == 22);
     return NS_OK;
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.h
+++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.h
@@ -118,9 +118,13 @@ private:
     PRUint8 mControlQoSBits;
     PRUint8 mDataQoSBits;
 };
 
 //-----------------------------------------------------------------------------
 
 extern nsFtpProtocolHandler *gFtpHandler;
 
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* gFTPLog;
+#endif
+
 #endif // !nsFtpProtocolHandler_h__
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -55,34 +55,16 @@
 #include "nsIUploadChannel2.h"
 #include "nsIProgressEventSink.h"
 #include "nsIURI.h"
 #include "nsIStringEnumerator.h"
 #include "nsISupportsPriority.h"
 #include "nsIApplicationCache.h"
 #include "nsIResumableChannel.h"
 
-#define DIE_WITH_ASYNC_OPEN_MSG()                                              \
-  do {                                                                         \
-    fprintf(stderr,                                                            \
-            "*&*&*&*&*&*&*&**&*&&*& FATAL ERROR: '%s' "                        \
-            "called after AsyncOpen: %s +%d",                                  \
-            __FUNCTION__, __FILE__, __LINE__);                                 \
-    NS_ABORT();                                                                \
-    return NS_ERROR_NOT_IMPLEMENTED;                                           \
-  } while (0)
-
-#define ENSURE_CALLED_BEFORE_ASYNC_OPEN()                                      \
-  if (mIsPending)                                                              \
-    DIE_WITH_ASYNC_OPEN_MSG();                                                 \
-  if (mWasOpened)                                                              \
-    DIE_WITH_ASYNC_OPEN_MSG();                                                 \
-  NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);                           \
-  NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
-
 namespace mozilla {
 namespace net {
 
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild. 
  * - Note that this class has nothing to do with nsBaseChannel, which is an
  *   earlier effort at a base class for channels that somehow never made it all