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