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