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.
5 #ifndef NET_FTP_FTP_NETWORK_TRANSACTION_H_
6 #define NET_FTP_FTP_NETWORK_TRANSACTION_H_
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"
25 class ClientSocketFactory
;
26 class FtpNetworkSession
;
29 class NET_EXPORT_PRIVATE FtpNetworkTransaction
: public FtpTransaction
{
31 FtpNetworkTransaction(FtpNetworkSession
* session
,
32 ClientSocketFactory
* socket_factory
);
33 virtual ~FtpNetworkTransaction();
35 virtual int Stop(int error
);
36 virtual int RestartIgnoringLastError(const CompletionCallback
& callback
);
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
;
51 FRIEND_TEST_ALL_PREFIXES(FtpNetworkTransactionTest
,
52 DownloadTransactionEvilPasvUnsafeHost
);
70 // Major categories of remote system types, as returned by SYST command.
79 // Data representation type, see RFC 959 section 3.1.1. Data Types.
80 // We only support the two most popular data types.
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
90 RESOURCE_TYPE_UNKNOWN
,
92 RESOURCE_TYPE_DIRECTORY
,
96 // Control connection states:
97 STATE_CTRL_RESOLVE_HOST
,
98 STATE_CTRL_RESOLVE_HOST_COMPLETE
,
100 STATE_CTRL_CONNECT_COMPLETE
,
102 STATE_CTRL_READ_COMPLETE
,
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:
119 STATE_DATA_CONNECT_COMPLETE
,
121 STATE_DATA_READ_COMPLETE
,
125 // Resets the members of the transaction so it can be restarted.
126 void ResetStateForRestart();
128 // Resets the data connection after an error and switches to |next_state|.
129 void ResetDataConnectionAfterError(State next_state
);
131 void DoCallback(int result
);
132 void OnIOComplete(int result
);
134 // Executes correct ProcessResponse + command_name function based on last
135 // issued command. Returns error code.
136 int ProcessCtrlResponse();
138 int SendFtpCommand(const std::string
& command
,
139 const std::string
& command_for_log
,
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;
146 // See if the request URL contains a typecode and make us respect it.
147 void DetectTypecode();
149 // Runs the state transition loop.
150 int DoLoop(int result
);
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
);
159 int DoCtrlConnectComplete(int result
);
161 int DoCtrlReadComplete(int result
);
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
);
191 int DoDataConnectComplete(int result
);
193 int DoDataReadComplete(int result
);
195 void RecordDataConnectionError(int result
);
197 Command command_sent_
;
199 CompletionCallback io_callback_
;
200 CompletionCallback user_callback_
;
202 scoped_refptr
<FtpNetworkSession
> session_
;
204 BoundNetLog net_log_
;
205 const FtpRequestInfo
* request_
;
206 FtpResponseInfo response_
;
208 // Cancels the outstanding request on destruction.
209 SingleRequestHostResolver resolver_
;
210 AddressList addresses_
;
212 // User buffer passed to the Read method for control socket.
213 scoped_refptr
<IOBuffer
> read_ctrl_buf_
;
215 scoped_ptr
<FtpCtrlResponseBuffer
> ctrl_response_buffer_
;
217 scoped_refptr
<IOBuffer
> read_data_buf_
;
218 int read_data_buf_len_
;
220 // Buffer holding the command line to be written to the control socket.
221 scoped_refptr
<IOBufferWithSize
> write_command_buf_
;
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_
;
229 SystemType system_type_
;
231 // Data type to be used for the TYPE command.
234 // Detected resource type (file or directory).
235 ResourceType resource_type_
;
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.
241 AuthCredentials credentials_
;
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_
;
247 int data_connection_port_
;
249 ClientSocketFactory
* socket_factory_
;
251 scoped_ptr
<StreamSocket
> ctrl_socket_
;
252 scoped_ptr
<StreamSocket
> data_socket_
;
256 // State to switch to after data connection is complete.
257 State state_after_data_connect_complete_
;
262 #endif // NET_FTP_FTP_NETWORK_TRANSACTION_H_