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