ftp_network_transaction.h revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 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/ref_counted.h"
13#include "base/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
22namespace net {
23
24class ClientSocket;
25class ClientSocketFactory;
26class FtpNetworkSession;
27
28class 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