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