Home | History | Annotate | Download | only in ftp
      1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.  Use of this
      2 // source code is governed by a BSD-style license that can be found in the
      3 // LICENSE file.
      4 
      5 #ifndef NET_FTP_FTP_NETWORK_TRANSACTION_H_
      6 #define NET_FTP_FTP_NETWORK_TRANSACTION_H_
      7 
      8 #include <string>
      9 #include <queue>
     10 #include <utility>
     11 #include <vector>
     12 
     13 #include "base/ref_counted.h"
     14 #include "base/scoped_ptr.h"
     15 #include "net/base/address_list.h"
     16 #include "net/base/host_resolver.h"
     17 #include "net/ftp/ftp_ctrl_response_buffer.h"
     18 #include "net/ftp/ftp_response_info.h"
     19 #include "net/ftp/ftp_transaction.h"
     20 
     21 namespace net {
     22 
     23 class ClientSocket;
     24 class ClientSocketFactory;
     25 class FtpNetworkSession;
     26 
     27 class FtpNetworkTransaction : public FtpTransaction {
     28  public:
     29   FtpNetworkTransaction(FtpNetworkSession* session,
     30                         ClientSocketFactory* socket_factory);
     31   virtual ~FtpNetworkTransaction();
     32 
     33   // FtpTransaction methods:
     34   virtual int Start(const FtpRequestInfo* request_info,
     35                     CompletionCallback* callback,
     36                     LoadLog* load_log);
     37   virtual int Stop(int error);
     38   virtual int RestartWithAuth(const std::wstring& username,
     39                               const std::wstring& password,
     40                               CompletionCallback* callback);
     41   virtual int RestartIgnoringLastError(CompletionCallback* callback);
     42   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     43   virtual const FtpResponseInfo* GetResponseInfo() const;
     44   virtual LoadState GetLoadState() const;
     45   virtual uint64 GetUploadProgress() const;
     46 
     47  private:
     48   enum Command {
     49     COMMAND_NONE,
     50     COMMAND_USER,
     51     COMMAND_PASS,
     52     COMMAND_ACCT,
     53     COMMAND_SYST,
     54     COMMAND_TYPE,
     55     COMMAND_PASV,
     56     COMMAND_PWD,
     57     COMMAND_SIZE,
     58     COMMAND_RETR,
     59     COMMAND_CWD,
     60     COMMAND_MLSD,
     61     COMMAND_LIST,
     62     COMMAND_MDTM,
     63     COMMAND_QUIT
     64   };
     65 
     66   enum ErrorClass {
     67     // The requested action was initiated. The client should expect another
     68     // reply before issuing the next command.
     69     ERROR_CLASS_INITIATED,
     70 
     71     // The requested action has been successfully completed.
     72     ERROR_CLASS_OK,
     73 
     74     // The command has been accepted, but to complete the operation, more
     75     // information must be sent by the client.
     76     ERROR_CLASS_INFO_NEEDED,
     77 
     78     // The command was not accepted and the requested action did not take place.
     79     // This condition is temporary, and the client is encouraged to restart the
     80     // command sequence.
     81     ERROR_CLASS_TRANSIENT_ERROR,
     82 
     83     // The command was not accepted and the requested action did not take place.
     84     // This condition is rather permanent, and the client is discouraged from
     85     // repeating the exact request.
     86     ERROR_CLASS_PERMANENT_ERROR,
     87   };
     88 
     89   // Major categories of remote system types, as returned by SYST command.
     90   enum SystemType {
     91     SYSTEM_TYPE_UNKNOWN,
     92     SYSTEM_TYPE_UNIX,
     93     SYSTEM_TYPE_WINDOWS,
     94     SYSTEM_TYPE_OS2,
     95     SYSTEM_TYPE_VMS,
     96   };
     97 
     98   // Resets the members of the transaction so it can be restarted.
     99   void ResetStateForRestart();
    100 
    101   void DoCallback(int result);
    102   void OnIOComplete(int result);
    103 
    104   // Executes correct ProcessResponse + command_name function based on last
    105   // issued command. Returns error code.
    106   int ProcessCtrlResponse();
    107 
    108   int SendFtpCommand(const std::string& command, Command cmd);
    109 
    110   // Return the error class for given response code. You should validate the
    111   // code to be in range 100-599.
    112   static ErrorClass GetErrorClass(int response_code);
    113 
    114   // Returns request path suitable to be included in an FTP command. If the path
    115   // will be used as a directory, |is_directory| should be true.
    116   std::string GetRequestPathForFtpCommand(bool is_directory) const;
    117 
    118   // Runs the state transition loop.
    119   int DoLoop(int result);
    120 
    121   // Each of these methods corresponds to a State value.  Those with an input
    122   // argument receive the result from the previous state.  If a method returns
    123   // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
    124   // next state method as the result arg.
    125   int DoCtrlInit();
    126   int DoCtrlInitComplete(int result);
    127   int DoCtrlResolveHost();
    128   int DoCtrlResolveHostComplete(int result);
    129   int DoCtrlConnect();
    130   int DoCtrlConnectComplete(int result);
    131   int DoCtrlRead();
    132   int DoCtrlReadComplete(int result);
    133   int DoCtrlWrite();
    134   int DoCtrlWriteComplete(int result);
    135   int DoCtrlWriteUSER();
    136   int ProcessResponseUSER(const FtpCtrlResponse& response);
    137   int DoCtrlWritePASS();
    138   int ProcessResponsePASS(const FtpCtrlResponse& response);
    139   int DoCtrlWriteACCT();
    140   int ProcessResponseACCT(const FtpCtrlResponse& response);
    141   int DoCtrlWriteSYST();
    142   int ProcessResponseSYST(const FtpCtrlResponse& response);
    143   int DoCtrlWritePWD();
    144   int ProcessResponsePWD(const FtpCtrlResponse& response);
    145   int DoCtrlWriteTYPE();
    146   int ProcessResponseTYPE(const FtpCtrlResponse& response);
    147   int DoCtrlWritePASV();
    148   int ProcessResponsePASV(const FtpCtrlResponse& response);
    149   int DoCtrlWriteRETR();
    150   int ProcessResponseRETR(const FtpCtrlResponse& response);
    151   int DoCtrlWriteSIZE();
    152   int ProcessResponseSIZE(const FtpCtrlResponse& response);
    153   int DoCtrlWriteCWD();
    154   int ProcessResponseCWD(const FtpCtrlResponse& response);
    155   int DoCtrlWriteMLSD();
    156   int ProcessResponseMLSD(const FtpCtrlResponse& response);
    157   int DoCtrlWriteLIST();
    158   int ProcessResponseLIST(const FtpCtrlResponse& response);
    159   int DoCtrlWriteMDTM();
    160   int ProcessResponseMDTM(const FtpCtrlResponse& response);
    161   int DoCtrlWriteQUIT();
    162   int ProcessResponseQUIT(const FtpCtrlResponse& response);
    163 
    164   int DoDataConnect();
    165   int DoDataConnectComplete(int result);
    166   int DoDataRead();
    167   int DoDataReadComplete(int result);
    168 
    169   void RecordDataConnectionError(int result);
    170 
    171   Command command_sent_;
    172 
    173   CompletionCallbackImpl<FtpNetworkTransaction> io_callback_;
    174   CompletionCallback* user_callback_;
    175 
    176   scoped_refptr<FtpNetworkSession> session_;
    177 
    178   scoped_refptr<LoadLog> load_log_;
    179   const FtpRequestInfo* request_;
    180   FtpResponseInfo response_;
    181 
    182   // Cancels the outstanding request on destruction.
    183   SingleRequestHostResolver resolver_;
    184   AddressList addresses_;
    185 
    186   // User buffer passed to the Read method for control socket.
    187   scoped_refptr<IOBuffer> read_ctrl_buf_;
    188 
    189   scoped_ptr<FtpCtrlResponseBuffer> ctrl_response_buffer_;
    190 
    191   scoped_refptr<IOBuffer> read_data_buf_;
    192   int read_data_buf_len_;
    193   int file_data_len_;
    194 
    195   // Buffer holding the command line to be written to the control socket.
    196   scoped_refptr<IOBufferWithSize> write_command_buf_;
    197 
    198   // Buffer passed to the Write method of control socket. It actually writes
    199   // to the write_command_buf_ at correct offset.
    200   scoped_refptr<DrainableIOBuffer> write_buf_;
    201 
    202   int last_error_;
    203 
    204   SystemType system_type_;
    205 
    206   // We get username and password as wstrings in RestartWithAuth, so they are
    207   // also kept as wstrings here.
    208   std::wstring username_;
    209   std::wstring password_;
    210 
    211   // Current directory on the remote server, as returned by last PWD command,
    212   // with any trailing slash removed.
    213   std::string current_remote_directory_;
    214 
    215   bool retr_failed_;
    216 
    217   int data_connection_port_;
    218 
    219   ClientSocketFactory* socket_factory_;
    220 
    221   scoped_ptr<ClientSocket> ctrl_socket_;
    222   scoped_ptr<ClientSocket> data_socket_;
    223 
    224   enum State {
    225     // Control connection states:
    226     STATE_CTRL_INIT,
    227     STATE_CTRL_INIT_COMPLETE,
    228     STATE_CTRL_RESOLVE_HOST,
    229     STATE_CTRL_RESOLVE_HOST_COMPLETE,
    230     STATE_CTRL_CONNECT,
    231     STATE_CTRL_CONNECT_COMPLETE,
    232     STATE_CTRL_READ,
    233     STATE_CTRL_READ_COMPLETE,
    234     STATE_CTRL_WRITE,
    235     STATE_CTRL_WRITE_COMPLETE,
    236     STATE_CTRL_WRITE_USER,
    237     STATE_CTRL_WRITE_PASS,
    238     STATE_CTRL_WRITE_ACCT,
    239     STATE_CTRL_WRITE_SYST,
    240     STATE_CTRL_WRITE_TYPE,
    241     STATE_CTRL_WRITE_PASV,
    242     STATE_CTRL_WRITE_PWD,
    243     STATE_CTRL_WRITE_RETR,
    244     STATE_CTRL_WRITE_SIZE,
    245     STATE_CTRL_WRITE_CWD,
    246     STATE_CTRL_WRITE_MLSD,
    247     STATE_CTRL_WRITE_LIST,
    248     STATE_CTRL_WRITE_MDTM,
    249     STATE_CTRL_WRITE_QUIT,
    250     // Data connection states:
    251     STATE_DATA_CONNECT,
    252     STATE_DATA_CONNECT_COMPLETE,
    253     STATE_DATA_READ,
    254     STATE_DATA_READ_COMPLETE,
    255     STATE_NONE
    256   };
    257   State next_state_;
    258 };
    259 
    260 }  // namespace net
    261 
    262 #endif  // NET_FTP_FTP_NETWORK_TRANSACTION_H_
    263