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