Home | History | Annotate | Download | only in ftp
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_FTP_FTP_NETWORK_TRANSACTION_H_
      6 #define NET_FTP_FTP_NETWORK_TRANSACTION_H_
      7 #pragma once
      8 
      9 #include <string>
     10 #include <utility>
     11 
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/string16.h"
     15 #include "net/base/address_list.h"
     16 #include "net/base/host_resolver.h"
     17 #include "net/base/net_log.h"
     18 #include "net/ftp/ftp_ctrl_response_buffer.h"
     19 #include "net/ftp/ftp_response_info.h"
     20 #include "net/ftp/ftp_transaction.h"
     21 
     22 namespace net {
     23 
     24 class ClientSocket;
     25 class ClientSocketFactory;
     26 class FtpNetworkSession;
     27 
     28 class FtpNetworkTransaction : public FtpTransaction {
     29  public:
     30   FtpNetworkTransaction(FtpNetworkSession* session,
     31                         ClientSocketFactory* socket_factory);
     32   virtual ~FtpNetworkTransaction();
     33 
     34   virtual int Stop(int error);
     35   virtual int RestartIgnoringLastError(CompletionCallback* callback);
     36 
     37   // FtpTransaction methods:
     38   virtual int Start(const FtpRequestInfo* request_info,
     39                     CompletionCallback* callback,
     40                     const BoundNetLog& net_log);
     41   virtual int RestartWithAuth(const string16& username,
     42                               const string16& password,
     43                               CompletionCallback* callback);
     44   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     45   virtual const FtpResponseInfo* GetResponseInfo() const;
     46   virtual LoadState GetLoadState() const;
     47   virtual uint64 GetUploadProgress() const;
     48 
     49  private:
     50   enum Command {
     51     COMMAND_NONE,
     52     COMMAND_USER,
     53     COMMAND_PASS,
     54     COMMAND_SYST,
     55     COMMAND_TYPE,
     56     COMMAND_EPSV,
     57     COMMAND_PASV,
     58     COMMAND_PWD,
     59     COMMAND_SIZE,
     60     COMMAND_RETR,
     61     COMMAND_CWD,
     62     COMMAND_LIST,
     63     COMMAND_QUIT,
     64   };
     65 
     66   // Major categories of remote system types, as returned by SYST command.
     67   enum SystemType {
     68     SYSTEM_TYPE_UNKNOWN,
     69     SYSTEM_TYPE_UNIX,
     70     SYSTEM_TYPE_WINDOWS,
     71     SYSTEM_TYPE_OS2,
     72     SYSTEM_TYPE_VMS,
     73   };
     74 
     75   // Data representation type, see RFC 959 section 3.1.1. Data Types.
     76   // We only support the two most popular data types.
     77   enum DataType {
     78     DATA_TYPE_ASCII,
     79     DATA_TYPE_IMAGE,
     80   };
     81 
     82   // In FTP we need to issue different commands depending on whether a resource
     83   // is a file or directory. If we don't know that, we're going to autodetect
     84   // it.
     85   enum ResourceType {
     86     RESOURCE_TYPE_UNKNOWN,
     87     RESOURCE_TYPE_FILE,
     88     RESOURCE_TYPE_DIRECTORY,
     89   };
     90 
     91   enum State {
     92     // Control connection states:
     93     STATE_CTRL_RESOLVE_HOST,
     94     STATE_CTRL_RESOLVE_HOST_COMPLETE,
     95     STATE_CTRL_CONNECT,
     96     STATE_CTRL_CONNECT_COMPLETE,
     97     STATE_CTRL_READ,
     98     STATE_CTRL_READ_COMPLETE,
     99     STATE_CTRL_WRITE,
    100     STATE_CTRL_WRITE_COMPLETE,
    101     STATE_CTRL_WRITE_USER,
    102     STATE_CTRL_WRITE_PASS,
    103     STATE_CTRL_WRITE_SYST,
    104     STATE_CTRL_WRITE_TYPE,
    105     STATE_CTRL_WRITE_EPSV,
    106     STATE_CTRL_WRITE_PASV,
    107     STATE_CTRL_WRITE_PWD,
    108     STATE_CTRL_WRITE_RETR,
    109     STATE_CTRL_WRITE_SIZE,
    110     STATE_CTRL_WRITE_CWD,
    111     STATE_CTRL_WRITE_LIST,
    112     STATE_CTRL_WRITE_QUIT,
    113     // Data connection states:
    114     STATE_DATA_CONNECT,
    115     STATE_DATA_CONNECT_COMPLETE,
    116     STATE_DATA_READ,
    117     STATE_DATA_READ_COMPLETE,
    118     STATE_NONE
    119   };
    120 
    121   // Resets the members of the transaction so it can be restarted.
    122   void ResetStateForRestart();
    123 
    124   void DoCallback(int result);
    125   void OnIOComplete(int result);
    126 
    127   // Executes correct ProcessResponse + command_name function based on last
    128   // issued command. Returns error code.
    129   int ProcessCtrlResponse();
    130 
    131   int SendFtpCommand(const std::string& command, Command cmd);
    132 
    133   // Returns request path suitable to be included in an FTP command. If the path
    134   // will be used as a directory, |is_directory| should be true.
    135   std::string GetRequestPathForFtpCommand(bool is_directory) const;
    136 
    137   // See if the request URL contains a typecode and make us respect it.
    138   void DetectTypecode();
    139 
    140   // Runs the state transition loop.
    141   int DoLoop(int result);
    142 
    143   // Each of these methods corresponds to a State value.  Those with an input
    144   // argument receive the result from the previous state.  If a method returns
    145   // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
    146   // next state method as the result arg.
    147   int DoCtrlResolveHost();
    148   int DoCtrlResolveHostComplete(int result);
    149   int DoCtrlConnect();
    150   int DoCtrlConnectComplete(int result);
    151   int DoCtrlRead();
    152   int DoCtrlReadComplete(int result);
    153   int DoCtrlWrite();
    154   int DoCtrlWriteComplete(int result);
    155   int DoCtrlWriteUSER();
    156   int ProcessResponseUSER(const FtpCtrlResponse& response);
    157   int DoCtrlWritePASS();
    158   int ProcessResponsePASS(const FtpCtrlResponse& response);
    159   int DoCtrlWriteSYST();
    160   int ProcessResponseSYST(const FtpCtrlResponse& response);
    161   int DoCtrlWritePWD();
    162   int ProcessResponsePWD(const FtpCtrlResponse& response);
    163   int DoCtrlWriteTYPE();
    164   int ProcessResponseTYPE(const FtpCtrlResponse& response);
    165   int DoCtrlWriteEPSV();
    166   int ProcessResponseEPSV(const FtpCtrlResponse& response);
    167   int DoCtrlWritePASV();
    168   int ProcessResponsePASV(const FtpCtrlResponse& response);
    169   int DoCtrlWriteRETR();
    170   int ProcessResponseRETR(const FtpCtrlResponse& response);
    171   int DoCtrlWriteSIZE();
    172   int ProcessResponseSIZE(const FtpCtrlResponse& response);
    173   int DoCtrlWriteCWD();
    174   int ProcessResponseCWD(const FtpCtrlResponse& response);
    175   int DoCtrlWriteLIST();
    176   int ProcessResponseLIST(const FtpCtrlResponse& response);
    177   int DoCtrlWriteQUIT();
    178   int ProcessResponseQUIT(const FtpCtrlResponse& response);
    179 
    180   int DoDataConnect();
    181   int DoDataConnectComplete(int result);
    182   int DoDataRead();
    183   int DoDataReadComplete(int result);
    184 
    185   void RecordDataConnectionError(int result);
    186 
    187   Command command_sent_;
    188 
    189   CompletionCallbackImpl<FtpNetworkTransaction> io_callback_;
    190   CompletionCallback* user_callback_;
    191 
    192   scoped_refptr<FtpNetworkSession> session_;
    193 
    194   BoundNetLog net_log_;
    195   const FtpRequestInfo* request_;
    196   FtpResponseInfo response_;
    197 
    198   // Cancels the outstanding request on destruction.
    199   SingleRequestHostResolver resolver_;
    200   AddressList addresses_;
    201 
    202   // User buffer passed to the Read method for control socket.
    203   scoped_refptr<IOBuffer> read_ctrl_buf_;
    204 
    205   scoped_ptr<FtpCtrlResponseBuffer> ctrl_response_buffer_;
    206 
    207   scoped_refptr<IOBuffer> read_data_buf_;
    208   int read_data_buf_len_;
    209 
    210   // Buffer holding the command line to be written to the control socket.
    211   scoped_refptr<IOBufferWithSize> write_command_buf_;
    212 
    213   // Buffer passed to the Write method of control socket. It actually writes
    214   // to the write_command_buf_ at correct offset.
    215   scoped_refptr<DrainableIOBuffer> write_buf_;
    216 
    217   int last_error_;
    218 
    219   SystemType system_type_;
    220 
    221   // Data type to be used for the TYPE command.
    222   DataType data_type_;
    223 
    224   // Detected resource type (file or directory).
    225   ResourceType resource_type_;
    226 
    227   // Initially we favour EPSV over PASV for transfers but should any
    228   // EPSV fail, we fall back to PASV for the duration of connection.
    229   bool use_epsv_;
    230 
    231   string16 username_;
    232   string16 password_;
    233 
    234   // Current directory on the remote server, as returned by last PWD command,
    235   // with any trailing slash removed.
    236   std::string current_remote_directory_;
    237 
    238   int data_connection_port_;
    239 
    240   ClientSocketFactory* socket_factory_;
    241 
    242   scoped_ptr<ClientSocket> ctrl_socket_;
    243   scoped_ptr<ClientSocket> data_socket_;
    244 
    245   State next_state_;
    246 };
    247 
    248 }  // namespace net
    249 
    250 #endif  // NET_FTP_FTP_NETWORK_TRANSACTION_H_
    251