netwerk/protocol/ftp/nsFTPChannel.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim:set ts=4 sts=4 sw=4 et cin: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsFTPChannel.h"
     8 #include "nsFtpConnectionThread.h"  // defines nsFtpState
    10 #include "nsThreadUtils.h"
    11 #include "mozilla/Attributes.h"
    13 #if defined(PR_LOGGING)
    14 extern PRLogModuleInfo* gFTPLog;
    15 #endif /* PR_LOGGING */
    17 // There are two transport connections established for an 
    18 // ftp connection. One is used for the command channel , and
    19 // the other for the data channel. The command channel is the first
    20 // connection made and is used to negotiate the second, data, channel.
    21 // The data channel is driven by the command channel and is either
    22 // initiated by the server (PORT command) or by the client (PASV command).
    23 // Client initiation is the most common case and is attempted first.
    25 //-----------------------------------------------------------------------------
    27 NS_IMPL_ISUPPORTS_INHERITED(nsFtpChannel,
    28                             nsBaseChannel,
    29                             nsIUploadChannel,
    30                             nsIResumableChannel,
    31                             nsIFTPChannel,
    32                             nsIProxiedChannel)
    34 //-----------------------------------------------------------------------------
    36 NS_IMETHODIMP
    37 nsFtpChannel::SetUploadStream(nsIInputStream *stream,
    38                               const nsACString &contentType,
    39                               int64_t contentLength)
    40 {
    41     NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
    43     mUploadStream = stream;
    45     // NOTE: contentLength is intentionally ignored here.
    47     return NS_OK;
    48 }
    50 NS_IMETHODIMP
    51 nsFtpChannel::GetUploadStream(nsIInputStream **stream)
    52 {
    53     NS_ENSURE_ARG_POINTER(stream);
    54     *stream = mUploadStream;
    55     NS_IF_ADDREF(*stream);
    56     return NS_OK;
    57 }
    59 //-----------------------------------------------------------------------------
    61 NS_IMETHODIMP
    62 nsFtpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID)
    63 {
    64     NS_ENSURE_TRUE(!Pending(), NS_ERROR_IN_PROGRESS);
    65     mEntityID = aEntityID;
    66     mStartPos = aStartPos;
    67     mResumeRequested = (mStartPos || !mEntityID.IsEmpty());
    68     return NS_OK;
    69 }
    71 NS_IMETHODIMP
    72 nsFtpChannel::GetEntityID(nsACString& entityID)
    73 {
    74     if (mEntityID.IsEmpty())
    75       return NS_ERROR_NOT_RESUMABLE;
    77     entityID = mEntityID;
    78     return NS_OK;
    79 }
    81 //-----------------------------------------------------------------------------
    82 NS_IMETHODIMP
    83 nsFtpChannel::GetProxyInfo(nsIProxyInfo** aProxyInfo)
    84 {
    85     *aProxyInfo = ProxyInfo();
    86     NS_IF_ADDREF(*aProxyInfo);
    87     return NS_OK;
    88 }
    90 //-----------------------------------------------------------------------------
    92 nsresult
    93 nsFtpChannel::OpenContentStream(bool async, nsIInputStream **result,
    94                                 nsIChannel** channel)
    95 {
    96     if (!async)
    97         return NS_ERROR_NOT_IMPLEMENTED;
    99     nsFtpState *state = new nsFtpState();
   100     if (!state)
   101         return NS_ERROR_OUT_OF_MEMORY;
   102     NS_ADDREF(state);
   104     nsresult rv = state->Init(this);
   105     if (NS_FAILED(rv)) {
   106         NS_RELEASE(state);
   107         return rv;
   108     }
   110     *result = state;
   111     return NS_OK;
   112 }
   114 bool
   115 nsFtpChannel::GetStatusArg(nsresult status, nsString &statusArg)
   116 {
   117     nsAutoCString host;
   118     URI()->GetHost(host);
   119     CopyUTF8toUTF16(host, statusArg);
   120     return true;
   121 }
   123 void
   124 nsFtpChannel::OnCallbacksChanged()
   125 {
   126     mFTPEventSink = nullptr;
   127 }
   129 //-----------------------------------------------------------------------------
   131 namespace {
   133 class FTPEventSinkProxy MOZ_FINAL : public nsIFTPEventSink
   134 {
   135 public:
   136     FTPEventSinkProxy(nsIFTPEventSink* aTarget)
   137         : mTarget(aTarget)
   138         , mTargetThread(do_GetCurrentThread())
   139     { }
   141     NS_DECL_THREADSAFE_ISUPPORTS
   142     NS_DECL_NSIFTPEVENTSINK
   144     class OnFTPControlLogRunnable : public nsRunnable
   145     {
   146     public:
   147         OnFTPControlLogRunnable(nsIFTPEventSink* aTarget,
   148                                 bool aServer,
   149                                 const char* aMessage)
   150             : mTarget(aTarget)
   151             , mServer(aServer)
   152             , mMessage(aMessage)
   153         { }
   155         NS_DECL_NSIRUNNABLE
   157     private:
   158         nsCOMPtr<nsIFTPEventSink> mTarget;
   159         bool mServer;
   160         nsCString mMessage;
   161     };
   163 private:
   164     nsCOMPtr<nsIFTPEventSink> mTarget;
   165     nsCOMPtr<nsIThread> mTargetThread;
   166 };
   168 NS_IMPL_ISUPPORTS(FTPEventSinkProxy, nsIFTPEventSink)
   170 NS_IMETHODIMP
   171 FTPEventSinkProxy::OnFTPControlLog(bool aServer, const char* aMsg)
   172 {
   173     nsRefPtr<OnFTPControlLogRunnable> r =
   174         new OnFTPControlLogRunnable(mTarget, aServer, aMsg);
   175     return mTargetThread->Dispatch(r, NS_DISPATCH_NORMAL);
   176 }
   178 NS_IMETHODIMP
   179 FTPEventSinkProxy::OnFTPControlLogRunnable::Run()
   180 {
   181     mTarget->OnFTPControlLog(mServer, mMessage.get());
   182     return NS_OK;
   183 }
   185 } // anonymous namespace
   187 void
   188 nsFtpChannel::GetFTPEventSink(nsCOMPtr<nsIFTPEventSink> &aResult)
   189 {
   190     if (!mFTPEventSink) {
   191         nsCOMPtr<nsIFTPEventSink> ftpSink;
   192         GetCallback(ftpSink);
   193         if (ftpSink) {
   194             mFTPEventSink = new FTPEventSinkProxy(ftpSink);
   195         }
   196     }
   197     aResult = mFTPEventSink;
   198 }
   200 void
   201 nsFtpChannel::ForcePending(bool aForcePending)
   202 {
   203     // Set true here so IsPending will return true.
   204     // Required for callback diversion from child back to parent. In such cases
   205     // OnStopRequest can be called in the parent before callbacks are diverted
   206     // back from the child to the listener in the parent.
   207     mForcePending = aForcePending;
   208 }
   210 NS_IMETHODIMP
   211 nsFtpChannel::IsPending(bool *result)
   212 {
   213   *result = Pending();
   214   return NS_OK;
   215 }
   217 bool
   218 nsFtpChannel::Pending() const
   219 {
   220   return nsBaseChannel::Pending() || mForcePending;
   221 }

mercurial