• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.  Use of this
2 // source code is governed by a BSD-style license that can be found in the
3 // 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 <queue>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/ref_counted.h"
14 #include "base/scoped_ptr.h"
15 #include "net/base/address_list.h"
16 #include "net/base/host_resolver.h"
17 #include "net/ftp/ftp_ctrl_response_buffer.h"
18 #include "net/ftp/ftp_response_info.h"
19 #include "net/ftp/ftp_transaction.h"
20 
21 namespace net {
22 
23 class ClientSocket;
24 class ClientSocketFactory;
25 class FtpNetworkSession;
26 
27 class FtpNetworkTransaction : public FtpTransaction {
28  public:
29   FtpNetworkTransaction(FtpNetworkSession* session,
30                         ClientSocketFactory* socket_factory);
31   virtual ~FtpNetworkTransaction();
32 
33   // FtpTransaction methods:
34   virtual int Start(const FtpRequestInfo* request_info,
35                     CompletionCallback* callback,
36                     LoadLog* load_log);
37   virtual int Stop(int error);
38   virtual int RestartWithAuth(const std::wstring& username,
39                               const std::wstring& password,
40                               CompletionCallback* callback);
41   virtual int RestartIgnoringLastError(CompletionCallback* callback);
42   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
43   virtual const FtpResponseInfo* GetResponseInfo() const;
44   virtual LoadState GetLoadState() const;
45   virtual uint64 GetUploadProgress() const;
46 
47  private:
48   enum Command {
49     COMMAND_NONE,
50     COMMAND_USER,
51     COMMAND_PASS,
52     COMMAND_ACCT,
53     COMMAND_SYST,
54     COMMAND_TYPE,
55     COMMAND_PASV,
56     COMMAND_PWD,
57     COMMAND_SIZE,
58     COMMAND_RETR,
59     COMMAND_CWD,
60     COMMAND_MLSD,
61     COMMAND_LIST,
62     COMMAND_MDTM,
63     COMMAND_QUIT
64   };
65 
66   enum ErrorClass {
67     // The requested action was initiated. The client should expect another
68     // reply before issuing the next command.
69     ERROR_CLASS_INITIATED,
70 
71     // The requested action has been successfully completed.
72     ERROR_CLASS_OK,
73 
74     // The command has been accepted, but to complete the operation, more
75     // information must be sent by the client.
76     ERROR_CLASS_INFO_NEEDED,
77 
78     // The command was not accepted and the requested action did not take place.
79     // This condition is temporary, and the client is encouraged to restart the
80     // command sequence.
81     ERROR_CLASS_TRANSIENT_ERROR,
82 
83     // The command was not accepted and the requested action did not take place.
84     // This condition is rather permanent, and the client is discouraged from
85     // repeating the exact request.
86     ERROR_CLASS_PERMANENT_ERROR,
87   };
88 
89   // Major categories of remote system types, as returned by SYST command.
90   enum SystemType {
91     SYSTEM_TYPE_UNKNOWN,
92     SYSTEM_TYPE_UNIX,
93     SYSTEM_TYPE_WINDOWS,
94     SYSTEM_TYPE_OS2,
95     SYSTEM_TYPE_VMS,
96   };
97 
98   // Resets the members of the transaction so it can be restarted.
99   void ResetStateForRestart();
100 
101   void DoCallback(int result);
102   void OnIOComplete(int result);
103 
104   // Executes correct ProcessResponse + command_name function based on last
105   // issued command. Returns error code.
106   int ProcessCtrlResponse();
107 
108   int SendFtpCommand(const std::string& command, Command cmd);
109 
110   // Return the error class for given response code. You should validate the
111   // code to be in range 100-599.
112   static ErrorClass GetErrorClass(int response_code);
113 
114   // Returns request path suitable to be included in an FTP command. If the path
115   // will be used as a directory, |is_directory| should be true.
116   std::string GetRequestPathForFtpCommand(bool is_directory) const;
117 
118   // Runs the state transition loop.
119   int DoLoop(int result);
120 
121   // Each of these methods corresponds to a State value.  Those with an input
122   // argument receive the result from the previous state.  If a method returns
123   // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
124   // next state method as the result arg.
125   int DoCtrlInit();
126   int DoCtrlInitComplete(int result);
127   int DoCtrlResolveHost();
128   int DoCtrlResolveHostComplete(int result);
129   int DoCtrlConnect();
130   int DoCtrlConnectComplete(int result);
131   int DoCtrlRead();
132   int DoCtrlReadComplete(int result);
133   int DoCtrlWrite();
134   int DoCtrlWriteComplete(int result);
135   int DoCtrlWriteUSER();
136   int ProcessResponseUSER(const FtpCtrlResponse& response);
137   int DoCtrlWritePASS();
138   int ProcessResponsePASS(const FtpCtrlResponse& response);
139   int DoCtrlWriteACCT();
140   int ProcessResponseACCT(const FtpCtrlResponse& response);
141   int DoCtrlWriteSYST();
142   int ProcessResponseSYST(const FtpCtrlResponse& response);
143   int DoCtrlWritePWD();
144   int ProcessResponsePWD(const FtpCtrlResponse& response);
145   int DoCtrlWriteTYPE();
146   int ProcessResponseTYPE(const FtpCtrlResponse& response);
147   int DoCtrlWritePASV();
148   int ProcessResponsePASV(const FtpCtrlResponse& response);
149   int DoCtrlWriteRETR();
150   int ProcessResponseRETR(const FtpCtrlResponse& response);
151   int DoCtrlWriteSIZE();
152   int ProcessResponseSIZE(const FtpCtrlResponse& response);
153   int DoCtrlWriteCWD();
154   int ProcessResponseCWD(const FtpCtrlResponse& response);
155   int DoCtrlWriteMLSD();
156   int ProcessResponseMLSD(const FtpCtrlResponse& response);
157   int DoCtrlWriteLIST();
158   int ProcessResponseLIST(const FtpCtrlResponse& response);
159   int DoCtrlWriteMDTM();
160   int ProcessResponseMDTM(const FtpCtrlResponse& response);
161   int DoCtrlWriteQUIT();
162   int ProcessResponseQUIT(const FtpCtrlResponse& response);
163 
164   int DoDataConnect();
165   int DoDataConnectComplete(int result);
166   int DoDataRead();
167   int DoDataReadComplete(int result);
168 
169   void RecordDataConnectionError(int result);
170 
171   Command command_sent_;
172 
173   CompletionCallbackImpl<FtpNetworkTransaction> io_callback_;
174   CompletionCallback* user_callback_;
175 
176   scoped_refptr<FtpNetworkSession> session_;
177 
178   scoped_refptr<LoadLog> load_log_;
179   const FtpRequestInfo* request_;
180   FtpResponseInfo response_;
181 
182   // Cancels the outstanding request on destruction.
183   SingleRequestHostResolver resolver_;
184   AddressList addresses_;
185 
186   // User buffer passed to the Read method for control socket.
187   scoped_refptr<IOBuffer> read_ctrl_buf_;
188 
189   scoped_ptr<FtpCtrlResponseBuffer> ctrl_response_buffer_;
190 
191   scoped_refptr<IOBuffer> read_data_buf_;
192   int read_data_buf_len_;
193   int file_data_len_;
194 
195   // Buffer holding the command line to be written to the control socket.
196   scoped_refptr<IOBufferWithSize> write_command_buf_;
197 
198   // Buffer passed to the Write method of control socket. It actually writes
199   // to the write_command_buf_ at correct offset.
200   scoped_refptr<DrainableIOBuffer> write_buf_;
201 
202   int last_error_;
203 
204   SystemType system_type_;
205 
206   // We get username and password as wstrings in RestartWithAuth, so they are
207   // also kept as wstrings here.
208   std::wstring username_;
209   std::wstring password_;
210 
211   // Current directory on the remote server, as returned by last PWD command,
212   // with any trailing slash removed.
213   std::string current_remote_directory_;
214 
215   bool retr_failed_;
216 
217   int data_connection_port_;
218 
219   ClientSocketFactory* socket_factory_;
220 
221   scoped_ptr<ClientSocket> ctrl_socket_;
222   scoped_ptr<ClientSocket> data_socket_;
223 
224   enum State {
225     // Control connection states:
226     STATE_CTRL_INIT,
227     STATE_CTRL_INIT_COMPLETE,
228     STATE_CTRL_RESOLVE_HOST,
229     STATE_CTRL_RESOLVE_HOST_COMPLETE,
230     STATE_CTRL_CONNECT,
231     STATE_CTRL_CONNECT_COMPLETE,
232     STATE_CTRL_READ,
233     STATE_CTRL_READ_COMPLETE,
234     STATE_CTRL_WRITE,
235     STATE_CTRL_WRITE_COMPLETE,
236     STATE_CTRL_WRITE_USER,
237     STATE_CTRL_WRITE_PASS,
238     STATE_CTRL_WRITE_ACCT,
239     STATE_CTRL_WRITE_SYST,
240     STATE_CTRL_WRITE_TYPE,
241     STATE_CTRL_WRITE_PASV,
242     STATE_CTRL_WRITE_PWD,
243     STATE_CTRL_WRITE_RETR,
244     STATE_CTRL_WRITE_SIZE,
245     STATE_CTRL_WRITE_CWD,
246     STATE_CTRL_WRITE_MLSD,
247     STATE_CTRL_WRITE_LIST,
248     STATE_CTRL_WRITE_MDTM,
249     STATE_CTRL_WRITE_QUIT,
250     // Data connection states:
251     STATE_DATA_CONNECT,
252     STATE_DATA_CONNECT_COMPLETE,
253     STATE_DATA_READ,
254     STATE_DATA_READ_COMPLETE,
255     STATE_NONE
256   };
257   State next_state_;
258 };
259 
260 }  // namespace net
261 
262 #endif  // NET_FTP_FTP_NETWORK_TRANSACTION_H_
263