LCOV - code coverage report
Current view: directory - netwerk/protocol/ftp - FTPChannelChild.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 224 0 0.0 %
Date: 2012-06-02 Functions: 55 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim: set sw=2 ts=8 et tw=80 : */
       3                 : 
       4                 : /* ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is mozilla.org code.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  *  The Mozilla Foundation
      21                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *   Alon Zakai <azakai@mozilla.com>
      26                 :  *   Josh Matthews <josh@joshmatthews.net>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      30                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : #include "mozilla/net/NeckoChild.h"
      43                 : #include "mozilla/net/FTPChannelChild.h"
      44                 : #include "nsFtpProtocolHandler.h"
      45                 : 
      46                 : #include "nsStringStream.h"
      47                 : #include "nsMimeTypes.h"
      48                 : #include "nsNetUtil.h"
      49                 : #include "nsIURIFixup.h"
      50                 : #include "nsCDefaultURIFixup.h"
      51                 : 
      52                 : #undef LOG
      53                 : #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
      54                 : 
      55                 : namespace mozilla {
      56                 : namespace net {
      57                 : 
      58               0 : FTPChannelChild::FTPChannelChild(nsIURI* uri)
      59                 : : mIPCOpen(false)
      60                 : , mEventQ(static_cast<nsIFTPChannel*>(this))
      61                 : , mCanceled(false)
      62                 : , mSuspendCount(0)
      63                 : , mIsPending(false)
      64                 : , mWasOpened(false)
      65                 : , mLastModifiedTime(0)
      66               0 : , mStartPos(0)
      67                 : {
      68               0 :   LOG(("Creating FTPChannelChild @%x\n", this));
      69                 :   // grab a reference to the handler to ensure that it doesn't go away.
      70               0 :   NS_ADDREF(gFtpHandler);
      71               0 :   SetURI(uri);
      72               0 : }
      73                 : 
      74               0 : FTPChannelChild::~FTPChannelChild()
      75                 : {
      76               0 :   LOG(("Destroying FTPChannelChild @%x\n", this));
      77               0 :   gFtpHandler->Release();
      78               0 : }
      79                 : 
      80                 : void
      81               0 : FTPChannelChild::AddIPDLReference()
      82                 : {
      83               0 :   NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
      84               0 :   mIPCOpen = true;
      85               0 :   AddRef();
      86               0 : }
      87                 : 
      88                 : void
      89               0 : FTPChannelChild::ReleaseIPDLReference()
      90                 : {
      91               0 :   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
      92               0 :   mIPCOpen = false;
      93               0 :   Release();
      94               0 : }
      95                 : 
      96                 : //-----------------------------------------------------------------------------
      97                 : // FTPChannelChild::nsISupports
      98                 : //-----------------------------------------------------------------------------
      99                 : 
     100               0 : NS_IMPL_ISUPPORTS_INHERITED5(FTPChannelChild,
     101                 :                              nsBaseChannel,
     102                 :                              nsIFTPChannel,
     103                 :                              nsIUploadChannel,
     104                 :                              nsIResumableChannel,
     105                 :                              nsIProxiedChannel,
     106                 :                              nsIChildChannel)
     107                 : 
     108                 : //-----------------------------------------------------------------------------
     109                 : 
     110                 : NS_IMETHODIMP
     111               0 : FTPChannelChild::GetLastModifiedTime(PRTime* lastModifiedTime)
     112                 : {
     113               0 :   *lastModifiedTime = mLastModifiedTime;
     114               0 :   return NS_OK;
     115                 : }
     116                 : 
     117                 : NS_IMETHODIMP
     118               0 : FTPChannelChild::SetLastModifiedTime(PRTime lastModifiedTime)
     119                 : {
     120               0 :   return NS_ERROR_NOT_AVAILABLE;
     121                 : }
     122                 : 
     123                 : NS_IMETHODIMP
     124               0 : FTPChannelChild::ResumeAt(PRUint64 aStartPos, const nsACString& aEntityID)
     125                 : {
     126               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
     127               0 :   mStartPos = aStartPos;
     128               0 :   mEntityID = aEntityID;
     129               0 :   return NS_OK;
     130                 : }
     131                 : 
     132                 : NS_IMETHODIMP
     133               0 : FTPChannelChild::GetEntityID(nsACString& entityID)
     134                 : {
     135               0 :   entityID = mEntityID;
     136               0 :   return NS_OK;
     137                 : }
     138                 : 
     139                 : NS_IMETHODIMP
     140               0 : FTPChannelChild::GetProxyInfo(nsIProxyInfo** aProxyInfo)
     141                 : {
     142               0 :   DROP_DEAD();
     143                 : }
     144                 : 
     145                 : NS_IMETHODIMP
     146               0 : FTPChannelChild::SetUploadStream(nsIInputStream* stream,
     147                 :                                  const nsACString& contentType,
     148                 :                                  PRInt32 contentLength)
     149                 : {
     150               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
     151               0 :   mUploadStream = stream;
     152                 :   // NOTE: contentLength is intentionally ignored here.
     153               0 :   return NS_OK;
     154                 : }
     155                 : 
     156                 : NS_IMETHODIMP
     157               0 : FTPChannelChild::GetUploadStream(nsIInputStream** stream)
     158                 : {
     159               0 :   NS_ENSURE_ARG_POINTER(stream);
     160               0 :   *stream = mUploadStream;
     161               0 :   NS_IF_ADDREF(*stream);
     162               0 :   return NS_OK;
     163                 : }
     164                 : 
     165                 : //-----------------------------------------------------------------------------
     166                 : 
     167                 : NS_IMETHODIMP
     168               0 : FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
     169                 : {
     170               0 :   LOG(("FTPChannelChild::AsyncOpen [this=%x]\n", this));
     171                 : 
     172               0 :   NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
     173               0 :   NS_ENSURE_ARG_POINTER(listener);
     174               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
     175               0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
     176                 : 
     177                 :   // Port checked in parent, but duplicate here so we can return with error
     178                 :   // immediately, as we've done since before e10s.
     179                 :   nsresult rv;
     180               0 :   rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate,
     181                 :                                                  // because in the child ipdl,
     182                 :                                                  // a typedef URI is defined...
     183               0 :   if (NS_FAILED(rv))
     184               0 :     return rv;
     185                 : 
     186                 :   // FIXME: like bug 558623, merge constructor+SendAsyncOpen into 1 IPC msg
     187               0 :   gNeckoChild->SendPFTPChannelConstructor(this);
     188               0 :   mListener = listener;
     189               0 :   mListenerContext = aContext;
     190                 : 
     191                 :   // add ourselves to the load group. 
     192               0 :   if (mLoadGroup)
     193               0 :     mLoadGroup->AddRequest(this, nsnull);
     194                 : 
     195                 :   SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID,
     196               0 :                 IPC::InputStream(mUploadStream));
     197                 : 
     198                 :   // The socket transport layer in the chrome process now has a logical ref to
     199                 :   // us until OnStopRequest is called.
     200               0 :   AddIPDLReference();
     201                 : 
     202               0 :   mIsPending = true;
     203               0 :   mWasOpened = true;
     204                 : 
     205               0 :   return rv;
     206                 : }
     207                 : 
     208                 : NS_IMETHODIMP
     209               0 : FTPChannelChild::IsPending(bool* result)
     210                 : {
     211               0 :   *result = mIsPending;
     212               0 :   return NS_OK;
     213                 : }
     214                 : 
     215                 : nsresult
     216               0 : FTPChannelChild::OpenContentStream(bool async,
     217                 :                                    nsIInputStream** stream,
     218                 :                                    nsIChannel** channel)
     219                 : {
     220               0 :   NS_RUNTIMEABORT("FTPChannel*Child* should never have OpenContentStream called!");
     221               0 :   return NS_OK;
     222                 : }
     223                 :   
     224                 : //-----------------------------------------------------------------------------
     225                 : // FTPChannelChild::PFTPChannelChild
     226                 : //-----------------------------------------------------------------------------
     227                 : 
     228                 : class FTPStartRequestEvent : public ChannelEvent
     229               0 : {
     230                 :  public:
     231               0 :   FTPStartRequestEvent(FTPChannelChild* aChild, const PRInt32& aContentLength,
     232                 :                        const nsCString& aContentType, const PRTime& aLastModified,
     233                 :                        const nsCString& aEntityID, const IPC::URI& aURI)
     234                 :   : mChild(aChild), mContentLength(aContentLength), mContentType(aContentType),
     235               0 :     mLastModified(aLastModified), mEntityID(aEntityID), mURI(aURI) {}
     236               0 :   void Run() { mChild->DoOnStartRequest(mContentLength, mContentType,
     237               0 :                                        mLastModified, mEntityID, mURI); }
     238                 :  private:
     239                 :   FTPChannelChild* mChild;
     240                 :   PRInt32 mContentLength;
     241                 :   nsCString mContentType;
     242                 :   PRTime mLastModified;
     243                 :   nsCString mEntityID;
     244                 :   IPC::URI mURI;
     245                 : };
     246                 : 
     247                 : bool
     248               0 : FTPChannelChild::RecvOnStartRequest(const PRInt32& aContentLength,
     249                 :                                     const nsCString& aContentType,
     250                 :                                     const PRTime& aLastModified,
     251                 :                                     const nsCString& aEntityID,
     252                 :                                     const IPC::URI& aURI)
     253                 : {
     254               0 :   if (mEventQ.ShouldEnqueue()) {
     255                 :     mEventQ.Enqueue(new FTPStartRequestEvent(this, aContentLength, aContentType,
     256               0 :                                              aLastModified, aEntityID, aURI));
     257                 :   } else {
     258                 :     DoOnStartRequest(aContentLength, aContentType, aLastModified,
     259               0 :                      aEntityID, aURI);
     260                 :   }
     261               0 :   return true;
     262                 : }
     263                 : 
     264                 : void
     265               0 : FTPChannelChild::DoOnStartRequest(const PRInt32& aContentLength,
     266                 :                                   const nsCString& aContentType,
     267                 :                                   const PRTime& aLastModified,
     268                 :                                   const nsCString& aEntityID,
     269                 :                                   const IPC::URI& aURI)
     270                 : {
     271               0 :   LOG(("FTPChannelChild::RecvOnStartRequest [this=%x]\n", this));
     272                 : 
     273               0 :   SetContentLength(aContentLength);
     274               0 :   SetContentType(aContentType);
     275               0 :   mLastModifiedTime = aLastModified;
     276               0 :   mEntityID = aEntityID;
     277                 : 
     278               0 :   nsCString spec;
     279               0 :   nsCOMPtr<nsIURI> uri(aURI);
     280               0 :   uri->GetSpec(spec);
     281               0 :   nsBaseChannel::URI()->SetSpec(spec);
     282                 : 
     283               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     284               0 :   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
     285               0 :   if (NS_FAILED(rv))
     286               0 :     Cancel(rv);
     287               0 : }
     288                 : 
     289                 : class FTPDataAvailableEvent : public ChannelEvent
     290               0 : {
     291                 :  public:
     292               0 :   FTPDataAvailableEvent(FTPChannelChild* aChild, const nsCString& aData,
     293                 :                         const PRUint32& aOffset, const PRUint32& aCount)
     294               0 :   : mChild(aChild), mData(aData), mOffset(aOffset), mCount(aCount) {}
     295               0 :   void Run() { mChild->DoOnDataAvailable(mData, mOffset, mCount); }
     296                 :  private:
     297                 :   FTPChannelChild* mChild;
     298                 :   nsCString mData;
     299                 :   PRUint32 mOffset, mCount;
     300                 : };
     301                 : 
     302                 : bool
     303               0 : FTPChannelChild::RecvOnDataAvailable(const nsCString& data,
     304                 :                                      const PRUint32& offset,
     305                 :                                      const PRUint32& count)
     306                 : {
     307               0 :   if (mEventQ.ShouldEnqueue()) {
     308               0 :     mEventQ.Enqueue(new FTPDataAvailableEvent(this, data, offset, count));
     309                 :   } else {
     310               0 :     DoOnDataAvailable(data, offset, count);
     311                 :   }
     312               0 :   return true;
     313                 : }
     314                 : 
     315                 : void
     316               0 : FTPChannelChild::DoOnDataAvailable(const nsCString& data,
     317                 :                                    const PRUint32& offset,
     318                 :                                    const PRUint32& count)
     319                 : {
     320               0 :   LOG(("FTPChannelChild::RecvOnDataAvailable [this=%x]\n", this));
     321                 : 
     322               0 :   if (mCanceled)
     323               0 :     return;
     324                 : 
     325                 :   // NOTE: the OnDataAvailable contract requires the client to read all the data
     326                 :   // in the inputstream.  This code relies on that ('data' will go away after
     327                 :   // this function).  Apparently the previous, non-e10s behavior was to actually
     328                 :   // support only reading part of the data, allowing later calls to read the
     329                 :   // rest.
     330               0 :   nsCOMPtr<nsIInputStream> stringStream;
     331               0 :   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream),
     332                 :                                       data.get(),
     333                 :                                       count,
     334               0 :                                       NS_ASSIGNMENT_DEPEND);
     335               0 :   if (NS_FAILED(rv)) {
     336               0 :     Cancel(rv);
     337                 :     return;
     338                 :   }
     339                 : 
     340               0 :   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     341               0 :   rv = mListener->OnDataAvailable(this, mListenerContext,
     342               0 :                                   stringStream, offset, count);
     343               0 :   if (NS_FAILED(rv))
     344               0 :     Cancel(rv);
     345               0 :   stringStream->Close();
     346                 : }
     347                 : 
     348                 : class FTPStopRequestEvent : public ChannelEvent
     349               0 : {
     350                 :  public:
     351               0 :   FTPStopRequestEvent(FTPChannelChild* aChild, const nsresult& aStatusCode)
     352               0 :   : mChild(aChild), mStatusCode(aStatusCode) {}
     353               0 :   void Run() { mChild->DoOnStopRequest(mStatusCode); }
     354                 :  private:
     355                 :   FTPChannelChild* mChild;
     356                 :   nsresult mStatusCode;
     357                 : };
     358                 : 
     359                 : bool
     360               0 : FTPChannelChild::RecvOnStopRequest(const nsresult& statusCode)
     361                 : {
     362               0 :   if (mEventQ.ShouldEnqueue()) {
     363               0 :     mEventQ.Enqueue(new FTPStopRequestEvent(this, statusCode));
     364                 :   } else {
     365               0 :     DoOnStopRequest(statusCode);
     366                 :   }
     367               0 :   return true;
     368                 : }
     369                 : 
     370                 : void
     371               0 : FTPChannelChild::DoOnStopRequest(const nsresult& statusCode)
     372                 : {
     373               0 :   LOG(("FTPChannelChild::RecvOnStopRequest [this=%x status=%u]\n",
     374                 :            this, statusCode));
     375                 : 
     376               0 :   if (!mCanceled)
     377               0 :     mStatus = statusCode;
     378                 : 
     379                 :   { // Ensure that all queued ipdl events are dispatched before
     380                 :     // we initiate protocol deletion below.
     381               0 :     mIsPending = false;
     382               0 :     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     383               0 :     (void)mListener->OnStopRequest(this, mListenerContext, statusCode);
     384               0 :     mListener = nsnull;
     385               0 :     mListenerContext = nsnull;
     386                 : 
     387               0 :     if (mLoadGroup)
     388               0 :       mLoadGroup->RemoveRequest(this, nsnull, statusCode);
     389                 :   }
     390                 : 
     391                 :   // This calls NeckoChild::DeallocPFTPChannel(), which deletes |this| if IPDL
     392                 :   // holds the last reference.  Don't rely on |this| existing after here!
     393               0 :   Send__delete__(this);
     394               0 : }
     395                 : 
     396                 : class FTPFailedAsyncOpenEvent : public ChannelEvent
     397               0 : {
     398                 :  public:
     399               0 :   FTPFailedAsyncOpenEvent(FTPChannelChild* aChild, nsresult aStatus)
     400               0 :   : mChild(aChild), mStatus(aStatus) {}
     401               0 :   void Run() { mChild->DoFailedAsyncOpen(mStatus); }
     402                 :  private:
     403                 :   FTPChannelChild* mChild;
     404                 :   nsresult mStatus;
     405                 : };
     406                 : 
     407                 : bool
     408               0 : FTPChannelChild::RecvFailedAsyncOpen(const nsresult& statusCode)
     409                 : {
     410               0 :   if (mEventQ.ShouldEnqueue()) {
     411               0 :     mEventQ.Enqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
     412                 :   } else {
     413               0 :     DoFailedAsyncOpen(statusCode);
     414                 :   }
     415               0 :   return true;
     416                 : }
     417                 : 
     418                 : void
     419               0 : FTPChannelChild::DoFailedAsyncOpen(const nsresult& statusCode)
     420                 : {
     421               0 :   mStatus = statusCode;
     422                 : 
     423               0 :   if (mLoadGroup)
     424               0 :     mLoadGroup->RemoveRequest(this, nsnull, statusCode);
     425                 : 
     426               0 :   if (mListener) {
     427               0 :     mListener->OnStartRequest(this, mListenerContext);
     428               0 :     mIsPending = false;
     429               0 :     mListener->OnStopRequest(this, mListenerContext, statusCode);
     430                 :   } else {
     431               0 :     mIsPending = false;
     432                 :   }
     433                 : 
     434               0 :   mListener = nsnull;
     435               0 :   mListenerContext = nsnull;
     436                 : 
     437               0 :   if (mIPCOpen)
     438               0 :     Send__delete__(this);
     439               0 : }
     440                 : 
     441                 : class FTPDeleteSelfEvent : public ChannelEvent
     442               0 : {
     443                 :  public:
     444               0 :   FTPDeleteSelfEvent(FTPChannelChild* aChild)
     445               0 :   : mChild(aChild) {}
     446               0 :   void Run() { mChild->DoDeleteSelf(); }
     447                 :  private:
     448                 :   FTPChannelChild* mChild;
     449                 : };
     450                 : 
     451                 : bool
     452               0 : FTPChannelChild::RecvDeleteSelf()
     453                 : {
     454               0 :   if (mEventQ.ShouldEnqueue()) {
     455               0 :     mEventQ.Enqueue(new FTPDeleteSelfEvent(this));
     456                 :   } else {
     457               0 :     DoDeleteSelf();
     458                 :   }
     459               0 :   return true;
     460                 : }
     461                 : 
     462                 : void
     463               0 : FTPChannelChild::DoDeleteSelf()
     464                 : {
     465               0 :   if (mIPCOpen)
     466               0 :     Send__delete__(this);
     467               0 : }
     468                 : 
     469                 : NS_IMETHODIMP
     470               0 : FTPChannelChild::Cancel(nsresult status)
     471                 : {
     472               0 :   if (mCanceled)
     473               0 :     return NS_OK;
     474                 : 
     475               0 :   mCanceled = true;
     476               0 :   mStatus = status;
     477               0 :   if (mIPCOpen)
     478               0 :     SendCancel(status);
     479               0 :   return NS_OK;
     480                 : }
     481                 : 
     482                 : NS_IMETHODIMP
     483               0 : FTPChannelChild::Suspend()
     484                 : {
     485               0 :   NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
     486               0 :   if (!mSuspendCount++) {
     487               0 :     SendSuspend();
     488               0 :     mEventQ.Suspend();
     489                 :   }
     490               0 :   return NS_OK;
     491                 : }
     492                 : 
     493                 : nsresult
     494               0 : FTPChannelChild::AsyncCall(void (FTPChannelChild::*funcPtr)(),
     495                 :                            nsRunnableMethod<FTPChannelChild> **retval)
     496                 : {
     497                 :   nsresult rv;
     498                 : 
     499               0 :   nsRefPtr<nsRunnableMethod<FTPChannelChild> > event = NS_NewRunnableMethod(this, funcPtr);
     500               0 :   rv = NS_DispatchToCurrentThread(event);
     501               0 :   if (NS_SUCCEEDED(rv) && retval) {
     502               0 :     *retval = event;
     503                 :   }
     504                 : 
     505               0 :   return rv;
     506                 : }
     507                 : 
     508                 : void
     509               0 : FTPChannelChild::CompleteResume()
     510                 : {
     511               0 :   mEventQ.Resume();
     512               0 : }
     513                 : 
     514                 : NS_IMETHODIMP
     515               0 : FTPChannelChild::Resume()
     516                 : {
     517               0 :   NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
     518                 : 
     519               0 :   if (!--mSuspendCount) {
     520               0 :     SendResume();
     521               0 :     AsyncCall(&FTPChannelChild::CompleteResume);
     522                 :   }
     523               0 :   return NS_OK;
     524                 : }
     525                 : 
     526                 : //-----------------------------------------------------------------------------
     527                 : // FTPChannelChild::nsIChildChannel
     528                 : //-----------------------------------------------------------------------------
     529                 : 
     530                 : NS_IMETHODIMP
     531               0 : FTPChannelChild::ConnectParent(PRUint32 id)
     532                 : {
     533                 :   // The socket transport in the chrome process now holds a logical ref to us
     534                 :   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
     535               0 :   AddIPDLReference();
     536                 : 
     537               0 :   if (!gNeckoChild->SendPFTPChannelConstructor(this))
     538               0 :     return NS_ERROR_FAILURE;
     539                 : 
     540               0 :   if (!SendConnectChannel(id))
     541               0 :     return NS_ERROR_FAILURE;
     542                 : 
     543               0 :   return NS_OK;
     544                 : }
     545                 : 
     546                 : NS_IMETHODIMP
     547               0 : FTPChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
     548                 :                                        nsISupports *aContext)
     549                 : {
     550               0 :   LOG(("FTPChannelChild::CompleteRedirectSetup [this=%x]\n", this));
     551                 : 
     552               0 :   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
     553               0 :   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
     554                 : 
     555               0 :   mIsPending = true;
     556               0 :   mWasOpened = true;
     557               0 :   mListener = listener;
     558               0 :   mListenerContext = aContext;
     559                 : 
     560                 :   // add ourselves to the load group.
     561               0 :   if (mLoadGroup)
     562               0 :     mLoadGroup->AddRequest(this, nsnull);
     563                 : 
     564                 :   // We already have an open IPDL connection to the parent. If on-modify-request
     565                 :   // listeners or load group observers canceled us, let the parent handle it
     566                 :   // and send it back to us naturally.
     567               0 :   return NS_OK;
     568                 : }
     569                 : 
     570                 : } // namespace net
     571                 : } // namespace mozilla
     572                 : 

Generated by: LCOV version 1.7