• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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