• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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 #include "net/ftp/ftp_network_transaction.h"
6 
7 #include "build/build_config.h"
8 
9 #include "base/ref_counted.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/mock_host_resolver.h"
12 #include "net/base/net_util.h"
13 #include "net/base/sys_addrinfo.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/ftp/ftp_network_session.h"
16 #include "net/ftp/ftp_request_info.h"
17 #include "net/socket/socket_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/platform_test.h"
20 
21 namespace {
22 
23 // Size we use for IOBuffers used to receive data from the test data socket.
24 const int kBufferSize = 128;
25 
26 }  // namespace
27 
28 namespace net {
29 
30 class FtpSocketDataProvider : public DynamicSocketDataProvider {
31  public:
32   enum State {
33     NONE,
34     PRE_USER,
35     PRE_PASSWD,
36     PRE_SYST,
37     PRE_PWD,
38     PRE_TYPE,
39     PRE_PASV,
40     PRE_SIZE,
41     PRE_MDTM,
42     PRE_MLSD,
43     PRE_LIST,
44     PRE_RETR,
45     PRE_PASV2,
46     PRE_CWD,
47     PRE_QUIT,
48     QUIT
49   };
50 
FtpSocketDataProvider()51   FtpSocketDataProvider()
52       : failure_injection_state_(NONE),
53         multiline_welcome_(false) {
54     Init();
55   }
56 
OnWrite(const std::string & data)57   virtual MockWriteResult OnWrite(const std::string& data) {
58     if (InjectFault())
59       return MockWriteResult(true, data.length());
60     switch (state()) {
61       case PRE_USER:
62         return Verify("USER anonymous\r\n", data, PRE_PASSWD,
63                       "331 Password needed\r\n");
64       case PRE_PASSWD:
65         {
66           const char* response_one = "230 Welcome\r\n";
67           const char* response_multi = "230- One\r\n230- Two\r\n230 Three\r\n";
68           return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
69                         multiline_welcome_ ? response_multi : response_one);
70         }
71       case PRE_SYST:
72         return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
73       case PRE_PWD:
74         return Verify("PWD\r\n", data, PRE_TYPE,
75                       "257 \"/\" is your current location\r\n");
76       case PRE_TYPE:
77         return Verify("TYPE I\r\n", data, PRE_PASV,
78                       "200 TYPE is now 8-bit binary\r\n");
79       case PRE_PASV:
80         return Verify("PASV\r\n", data, PRE_SIZE,
81                       "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
82       case PRE_PASV2:
83         // Parser should also accept format without parentheses.
84         return Verify("PASV\r\n", data, PRE_CWD,
85                       "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
86       case PRE_QUIT:
87         return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
88       default:
89         NOTREACHED() << "State not handled " << state();
90         return MockWriteResult(true, ERR_UNEXPECTED);
91     }
92   }
93 
InjectFailure(State state,State next_state,const char * response)94   void InjectFailure(State state, State next_state, const char* response) {
95     DCHECK_EQ(NONE, failure_injection_state_);
96     DCHECK_NE(NONE, state);
97     DCHECK_NE(NONE, next_state);
98     DCHECK_NE(state, next_state);
99     failure_injection_state_ = state;
100     failure_injection_next_state_ = next_state;
101     fault_response_ = response;
102   }
103 
state() const104   State state() const {
105     return state_;
106   }
107 
Reset()108   virtual void Reset() {
109     DynamicSocketDataProvider::Reset();
110     Init();
111   }
112 
set_multiline_welcome(bool multiline)113   void set_multiline_welcome(bool multiline) {
114     multiline_welcome_ = multiline;
115   }
116 
117  protected:
Init()118   void Init() {
119     state_ = PRE_USER;
120     SimulateRead("220 host TestFTPd\r\n");
121   }
122 
123   // If protocol fault injection has been requested, adjusts state and mocked
124   // read and returns true.
InjectFault()125   bool InjectFault() {
126     if (state_ != failure_injection_state_)
127       return false;
128     SimulateRead(fault_response_);
129     state_ = failure_injection_next_state_;
130     return true;
131   }
132 
Verify(const std::string & expected,const std::string & data,State next_state,const char * next_read)133   MockWriteResult Verify(const std::string& expected,
134                          const std::string& data,
135                          State next_state,
136                          const char* next_read) {
137     EXPECT_EQ(expected, data);
138     if (expected == data) {
139       state_ = next_state;
140       SimulateRead(next_read);
141       return MockWriteResult(true, data.length());
142     }
143     return MockWriteResult(true, ERR_UNEXPECTED);
144   }
145 
146  private:
147   State state_;
148   State failure_injection_state_;
149   State failure_injection_next_state_;
150   const char* fault_response_;
151 
152   // If true, we will send multiple 230 lines as response after PASS.
153   bool multiline_welcome_;
154 
155   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
156 };
157 
158 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
159  public:
FtpSocketDataProviderDirectoryListing()160   FtpSocketDataProviderDirectoryListing() {
161   }
162 
OnWrite(const std::string & data)163   virtual MockWriteResult OnWrite(const std::string& data) {
164     if (InjectFault())
165       return MockWriteResult(true, data.length());
166     switch (state()) {
167       case PRE_SIZE:
168         return Verify("SIZE /\r\n", data, PRE_MDTM,
169                       "550 I can only retrieve regular files\r\n");
170       case PRE_MDTM:
171         return Verify("MDTM /\r\n", data, PRE_RETR,
172                       "213 20070221112533\r\n");
173       case PRE_RETR:
174         return Verify("RETR /\r\n", data, PRE_PASV2,
175                       "550 Can't download directory\r\n");
176 
177       case PRE_CWD:
178         return Verify("CWD /\r\n", data, PRE_MLSD, "200 OK\r\n");
179       case PRE_MLSD:
180         return Verify("MLSD\r\n", data, PRE_QUIT,
181                       "150 Accepted data connection\r\n"
182                       "226 MLSD complete\r\n");
183       case PRE_LIST:
184         return Verify("LIST\r\n", data, PRE_QUIT, "200 OK\r\n");
185       default:
186         return FtpSocketDataProvider::OnWrite(data);
187     }
188   }
189 
190  private:
191   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
192 };
193 
194 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
195  public:
FtpSocketDataProviderVMSDirectoryListing()196   FtpSocketDataProviderVMSDirectoryListing() {
197   }
198 
OnWrite(const std::string & data)199   virtual MockWriteResult OnWrite(const std::string& data) {
200     if (InjectFault())
201       return MockWriteResult(true, data.length());
202     switch (state()) {
203       case PRE_SYST:
204         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
205       case PRE_PWD:
206         return Verify("PWD\r\n", data, PRE_TYPE,
207                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
208       case PRE_SIZE:
209         return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_MDTM,
210                       "550 I can only retrieve regular files\r\n");
211       case PRE_MDTM:
212         return Verify("MDTM ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_RETR,
213                       "213 20070221112533\r\n");
214       case PRE_RETR:
215         return Verify("RETR ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_PASV2,
216                       "550 Can't download directory\r\n");
217       case PRE_CWD:
218         return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data, PRE_MLSD,
219                       "200 OK\r\n");
220       case PRE_MLSD:
221         return Verify("MLSD\r\n", data, PRE_LIST, "500 Invalid command\r\n");
222       case PRE_LIST:
223         return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
224       default:
225         return FtpSocketDataProvider::OnWrite(data);
226     }
227   }
228 
229  private:
230   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
231 };
232 
233 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
234     : public FtpSocketDataProvider {
235  public:
FtpSocketDataProviderVMSDirectoryListingRootDirectory()236   FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
237   }
238 
OnWrite(const std::string & data)239   virtual MockWriteResult OnWrite(const std::string& data) {
240     if (InjectFault())
241       return MockWriteResult(true, data.length());
242     switch (state()) {
243       case PRE_SYST:
244         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
245       case PRE_PWD:
246         return Verify("PWD\r\n", data, PRE_TYPE,
247                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
248       case PRE_SIZE:
249         return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_MDTM,
250                       "550 I can only retrieve regular files\r\n");
251       case PRE_MDTM:
252         return Verify("MDTM ANONYMOUS_ROOT\r\n", data, PRE_RETR,
253                       "213 20070221112533\r\n");
254       case PRE_RETR:
255         return Verify("RETR ANONYMOUS_ROOT\r\n", data, PRE_PASV2,
256                       "550 Can't download directory\r\n");
257       case PRE_CWD:
258         return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data, PRE_MLSD,
259                       "200 OK\r\n");
260       case PRE_MLSD:
261         return Verify("MLSD\r\n", data, PRE_LIST, "500 Invalid command\r\n");
262       case PRE_LIST:
263         return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
264       default:
265         return FtpSocketDataProvider::OnWrite(data);
266     }
267   }
268 
269  private:
270   DISALLOW_COPY_AND_ASSIGN(
271       FtpSocketDataProviderVMSDirectoryListingRootDirectory);
272 };
273 
274 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
275  public:
FtpSocketDataProviderFileDownload()276   FtpSocketDataProviderFileDownload() {
277   }
278 
OnWrite(const std::string & data)279   virtual MockWriteResult OnWrite(const std::string& data) {
280     if (InjectFault())
281       return MockWriteResult(true, data.length());
282     switch (state()) {
283       case PRE_SIZE:
284         return Verify("SIZE /file\r\n", data, PRE_MDTM,
285                       "213 18\r\n");
286       case PRE_MDTM:
287         return Verify("MDTM /file\r\n", data, PRE_RETR,
288                       "213 20070221112533\r\n");
289       case PRE_RETR:
290         return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
291       default:
292         return FtpSocketDataProvider::OnWrite(data);
293     }
294   }
295 
296  private:
297   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
298 };
299 
300 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
301  public:
FtpSocketDataProviderVMSFileDownload()302   FtpSocketDataProviderVMSFileDownload() {
303   }
304 
OnWrite(const std::string & data)305   virtual MockWriteResult OnWrite(const std::string& data) {
306     if (InjectFault())
307       return MockWriteResult(true, data.length());
308     switch (state()) {
309       case PRE_SYST:
310         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
311       case PRE_PWD:
312         return Verify("PWD\r\n", data, PRE_TYPE,
313                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
314       case PRE_SIZE:
315         return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_MDTM,
316                       "213 18\r\n");
317       case PRE_MDTM:
318         return Verify("MDTM ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_RETR,
319                       "213 20070221112533\r\n");
320       case PRE_RETR:
321         return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
322                       "200 OK\r\n");
323       default:
324         return FtpSocketDataProvider::OnWrite(data);
325     }
326   }
327 
328  private:
329   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
330 };
331 
332 class FtpSocketDataProviderEscaping : public FtpSocketDataProvider {
333  public:
FtpSocketDataProviderEscaping()334   FtpSocketDataProviderEscaping() {
335   }
336 
OnWrite(const std::string & data)337   virtual MockWriteResult OnWrite(const std::string& data) {
338     if (InjectFault())
339       return MockWriteResult(true, data.length());
340     switch (state()) {
341       case PRE_SIZE:
342         return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_MDTM,
343                       "213 18\r\n");
344       case PRE_MDTM:
345         return Verify("MDTM / !\"#$%y\200\201\r\n", data, PRE_RETR,
346                       "213 20070221112533\r\n");
347       case PRE_RETR:
348         return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
349                       "200 OK\r\n");
350       default:
351         return FtpSocketDataProvider::OnWrite(data);
352     }
353   }
354 
355  private:
356   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
357 };
358 
359 class FtpSocketDataProviderFileDownloadAcceptedDataConnection
360     : public FtpSocketDataProviderFileDownload {
361  public:
FtpSocketDataProviderFileDownloadAcceptedDataConnection()362   FtpSocketDataProviderFileDownloadAcceptedDataConnection() {
363   }
364 
OnWrite(const std::string & data)365   virtual MockWriteResult OnWrite(const std::string& data) {
366     if (InjectFault())
367       return MockWriteResult(true, data.length());
368     switch (state()) {
369       case PRE_RETR:
370         return Verify("RETR /file\r\n", data, PRE_QUIT,
371                       "150 Accepted Data Connection\r\n");
372       default:
373         return FtpSocketDataProviderFileDownload::OnWrite(data);
374     }
375   }
376 
377  private:
378   DISALLOW_COPY_AND_ASSIGN(
379       FtpSocketDataProviderFileDownloadAcceptedDataConnection);
380 };
381 
382 class FtpSocketDataProviderFileDownloadTransferStarting
383     : public FtpSocketDataProviderFileDownload {
384  public:
FtpSocketDataProviderFileDownloadTransferStarting()385   FtpSocketDataProviderFileDownloadTransferStarting() {
386   }
387 
OnWrite(const std::string & data)388   virtual MockWriteResult OnWrite(const std::string& data) {
389     if (InjectFault())
390       return MockWriteResult(true, data.length());
391     switch (state()) {
392       case PRE_RETR:
393         return Verify("RETR /file\r\n", data, PRE_QUIT,
394                       "125-Data connection already open.\r\n"
395                       "125  Transfer starting.\r\n"
396                       "226 Transfer complete.\r\n");
397       default:
398         return FtpSocketDataProviderFileDownload::OnWrite(data);
399     }
400   }
401 
402  private:
403   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
404 };
405 
406 class FtpSocketDataProviderDirectoryListingTransferStarting
407     : public FtpSocketDataProviderDirectoryListing {
408  public:
FtpSocketDataProviderDirectoryListingTransferStarting()409   FtpSocketDataProviderDirectoryListingTransferStarting() {
410   }
411 
OnWrite(const std::string & data)412   virtual MockWriteResult OnWrite(const std::string& data) {
413     if (InjectFault())
414       return MockWriteResult(true, data.length());
415     switch (state()) {
416       case PRE_LIST:
417         return Verify("LIST\r\n", data, PRE_QUIT,
418                       "125-Data connection already open.\r\n"
419                       "125  Transfer starting.\r\n"
420                       "226 Transfer complete.\r\n");
421       default:
422         return FtpSocketDataProviderDirectoryListing::OnWrite(data);
423     }
424   }
425 
426  private:
427   DISALLOW_COPY_AND_ASSIGN(
428       FtpSocketDataProviderDirectoryListingTransferStarting);
429 };
430 
431 class FtpSocketDataProviderFileDownloadInvalidResponse
432     : public FtpSocketDataProviderFileDownload {
433  public:
FtpSocketDataProviderFileDownloadInvalidResponse()434   FtpSocketDataProviderFileDownloadInvalidResponse() {
435   }
436 
OnWrite(const std::string & data)437   virtual MockWriteResult OnWrite(const std::string& data) {
438     if (InjectFault())
439       return MockWriteResult(true, data.length());
440     switch (state()) {
441       case PRE_SIZE:
442         return Verify("SIZE /file\r\n", data, PRE_QUIT,
443                       "500 Evil Response\r\n"
444                       "500 More Evil\r\n");
445       default:
446         return FtpSocketDataProviderFileDownload::OnWrite(data);
447     }
448   }
449 
450  private:
451   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
452 };
453 
454 class FtpSocketDataProviderFileDownloadRetrFail
455     : public FtpSocketDataProviderFileDownload {
456  public:
FtpSocketDataProviderFileDownloadRetrFail()457   FtpSocketDataProviderFileDownloadRetrFail() {
458   }
459 
OnWrite(const std::string & data)460   virtual MockWriteResult OnWrite(const std::string& data) {
461     if (InjectFault())
462       return MockWriteResult(true, data.length());
463     switch (state()) {
464       case PRE_CWD:
465         return Verify("CWD /file\r\n", data, PRE_QUIT,
466                       "550 file is a directory\r\n");
467       default:
468         return FtpSocketDataProviderFileDownload::OnWrite(data);
469     }
470   }
471 
472  private:
473   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadRetrFail);
474 };
475 
476 class FtpSocketDataProviderEvilPasv : public FtpSocketDataProviderFileDownload {
477  public:
FtpSocketDataProviderEvilPasv(const char * pasv_response,State expected_state)478   explicit FtpSocketDataProviderEvilPasv(const char* pasv_response,
479                                         State expected_state)
480       : pasv_response_(pasv_response),
481         expected_state_(expected_state) {
482   }
483 
OnWrite(const std::string & data)484   virtual MockWriteResult OnWrite(const std::string& data) {
485     if (InjectFault())
486       return MockWriteResult(true, data.length());
487     switch (state()) {
488       case PRE_PASV:
489         return Verify("PASV\r\n", data, expected_state_, pasv_response_);
490       default:
491         return FtpSocketDataProviderFileDownload::OnWrite(data);
492     }
493   }
494 
495  private:
496   const char* pasv_response_;
497   const State expected_state_;
498 
499   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
500 };
501 
502 class FtpSocketDataProviderEvilLogin : public FtpSocketDataProviderFileDownload {
503  public:
FtpSocketDataProviderEvilLogin(const char * expected_user,const char * expected_password)504   FtpSocketDataProviderEvilLogin(const char* expected_user,
505                                 const char* expected_password)
506       : expected_user_(expected_user),
507         expected_password_(expected_password) {
508   }
509 
OnWrite(const std::string & data)510   virtual MockWriteResult OnWrite(const std::string& data) {
511     if (InjectFault())
512       return MockWriteResult(true, data.length());
513     switch (state()) {
514       case PRE_USER:
515         return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
516                       PRE_PASSWD, "331 Password needed\r\n");
517       case PRE_PASSWD:
518         return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
519                       PRE_SYST, "230 Welcome\r\n");
520       default:
521         return FtpSocketDataProviderFileDownload::OnWrite(data);
522     }
523   }
524 
525  private:
526   const char* expected_user_;
527   const char* expected_password_;
528 
529   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
530 };
531 
532 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
533  public:
FtpSocketDataProviderCloseConnection()534   FtpSocketDataProviderCloseConnection() {
535   }
536 
OnWrite(const std::string & data)537   virtual MockWriteResult OnWrite(const std::string& data) {
538     if (InjectFault())
539       return MockWriteResult(true, data.length());
540     switch (state()) {
541       case PRE_USER:
542         return Verify("USER anonymous\r\n", data,
543                       PRE_QUIT, "");
544       default:
545         return FtpSocketDataProvider::OnWrite(data);
546     }
547   }
548 
549  private:
550   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
551 };
552 
553 class FtpNetworkTransactionTest : public PlatformTest {
554  public:
FtpNetworkTransactionTest()555   FtpNetworkTransactionTest()
556       : host_resolver_(new MockHostResolver),
557         session_(new FtpNetworkSession(host_resolver_)),
558         transaction_(session_.get(), &mock_socket_factory_) {
559   }
560 
561  protected:
GetRequestInfo(const std::string & url)562   FtpRequestInfo GetRequestInfo(const std::string& url) {
563     FtpRequestInfo info;
564     info.url = GURL(url);
565     return info;
566   }
567 
ExecuteTransaction(FtpSocketDataProvider * ctrl_socket,const char * request,int expected_result)568   void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
569                           const char* request,
570                           int expected_result) {
571     std::string mock_data("mock-data");
572     MockRead data_reads[] = {
573       MockRead(mock_data.c_str()),
574     };
575     // For compatibility with FileZilla, the transaction code will use two data
576     // sockets for directory requests. For more info see http://crbug.com/25316.
577     StaticSocketDataProvider data1(data_reads, NULL);
578     StaticSocketDataProvider data2(data_reads, NULL);
579     mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
580     mock_socket_factory_.AddSocketDataProvider(&data1);
581     mock_socket_factory_.AddSocketDataProvider(&data2);
582     FtpRequestInfo request_info = GetRequestInfo(request);
583     EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
584     ASSERT_EQ(ERR_IO_PENDING,
585               transaction_.Start(&request_info, &callback_, NULL));
586     EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
587     EXPECT_EQ(expected_result, callback_.WaitForResult());
588     EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
589     if (expected_result == OK) {
590       scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
591       memset(io_buffer->data(), 0, kBufferSize);
592       ASSERT_EQ(ERR_IO_PENDING,
593                 transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
594       EXPECT_EQ(static_cast<int>(mock_data.length()),
595                 callback_.WaitForResult());
596       EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
597     }
598     EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
599   }
600 
TransactionFailHelper(FtpSocketDataProvider * ctrl_socket,const char * request,FtpSocketDataProvider::State state,FtpSocketDataProvider::State next_state,const char * response,int expected_result)601   void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
602                              const char* request,
603                              FtpSocketDataProvider::State state,
604                              FtpSocketDataProvider::State next_state,
605                              const char* response,
606                              int expected_result) {
607     ctrl_socket->InjectFailure(state, next_state, response);
608     ExecuteTransaction(ctrl_socket, request, expected_result);
609   }
610 
611   scoped_refptr<MockHostResolver> host_resolver_;
612   scoped_refptr<FtpNetworkSession> session_;
613   MockClientSocketFactory mock_socket_factory_;
614   FtpNetworkTransaction transaction_;
615   TestCompletionCallback callback_;
616 };
617 
TEST_F(FtpNetworkTransactionTest,FailedLookup)618 TEST_F(FtpNetworkTransactionTest, FailedLookup) {
619   FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
620   host_resolver_->rules()->AddSimulatedFailure("badhost");
621   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
622   ASSERT_EQ(ERR_IO_PENDING,
623             transaction_.Start(&request_info, &callback_, NULL));
624   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
625   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
626 }
627 
TEST_F(FtpNetworkTransactionTest,DirectoryTransaction)628 TEST_F(FtpNetworkTransactionTest, DirectoryTransaction) {
629   FtpSocketDataProviderDirectoryListing ctrl_socket;
630   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
631 }
632 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcome)633 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
634   FtpSocketDataProviderDirectoryListing ctrl_socket;
635   ctrl_socket.set_multiline_welcome(true);
636   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
637 }
638 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionShortReads2)639 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
640   FtpSocketDataProviderDirectoryListing ctrl_socket;
641   ctrl_socket.set_short_read_limit(2);
642   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
643 }
644 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionShortReads5)645 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
646   FtpSocketDataProviderDirectoryListing ctrl_socket;
647   ctrl_socket.set_short_read_limit(5);
648   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
649 }
650 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcomeShort)651 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
652   FtpSocketDataProviderDirectoryListing ctrl_socket;
653   // The client will not consume all three 230 lines. That's good, we want to
654   // test that scenario.
655   ctrl_socket.allow_unconsumed_reads(true);
656   ctrl_socket.set_multiline_welcome(true);
657   ctrl_socket.set_short_read_limit(5);
658   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
659 }
660 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionVMS)661 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
662   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
663   ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
664 }
665 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionVMSRootDirectory)666 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
667   FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
668   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
669 }
670 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionTransferStarting)671 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
672   FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
673   ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
674 }
675 
TEST_F(FtpNetworkTransactionTest,DownloadTransaction)676 TEST_F(FtpNetworkTransactionTest, DownloadTransaction) {
677   FtpSocketDataProviderFileDownload ctrl_socket;
678   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
679 }
680 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionMultilineWelcome)681 TEST_F(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
682   FtpSocketDataProviderFileDownload ctrl_socket;
683   ctrl_socket.set_multiline_welcome(true);
684   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
685 }
686 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionShortReads2)687 TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
688   FtpSocketDataProviderFileDownload ctrl_socket;
689   ctrl_socket.set_short_read_limit(2);
690   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
691 }
692 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionShortReads5)693 TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
694   FtpSocketDataProviderFileDownload ctrl_socket;
695   ctrl_socket.set_short_read_limit(5);
696   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
697 }
698 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionVMS)699 TEST_F(FtpNetworkTransactionTest, DownloadTransactionVMS) {
700   FtpSocketDataProviderVMSFileDownload ctrl_socket;
701   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
702 }
703 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionAcceptedDataConnection)704 TEST_F(FtpNetworkTransactionTest, DownloadTransactionAcceptedDataConnection) {
705   FtpSocketDataProviderFileDownloadAcceptedDataConnection ctrl_socket;
706   std::string mock_data("mock-data");
707   MockRead data_reads[] = {
708     MockRead(mock_data.c_str()),
709   };
710   StaticSocketDataProvider data_socket1(data_reads, NULL);
711   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
712   mock_socket_factory_.AddSocketDataProvider(&data_socket1);
713   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
714 
715   // Start the transaction.
716   ASSERT_EQ(ERR_IO_PENDING,
717             transaction_.Start(&request_info, &callback_, NULL));
718   EXPECT_EQ(OK, callback_.WaitForResult());
719 
720   // The transaction fires the callback when we can start reading data.
721   EXPECT_EQ(FtpSocketDataProvider::PRE_QUIT, ctrl_socket.state());
722   EXPECT_EQ(LOAD_STATE_SENDING_REQUEST, transaction_.GetLoadState());
723   scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
724   memset(io_buffer->data(), 0, kBufferSize);
725   ASSERT_EQ(ERR_IO_PENDING,
726             transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
727   EXPECT_EQ(LOAD_STATE_READING_RESPONSE, transaction_.GetLoadState());
728   EXPECT_EQ(static_cast<int>(mock_data.length()),
729             callback_.WaitForResult());
730   EXPECT_EQ(LOAD_STATE_READING_RESPONSE, transaction_.GetLoadState());
731   EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
732 
733   // FTP server should disconnect the data socket. It is also a signal for the
734   // FtpNetworkTransaction that the data transfer is finished.
735   ClientSocket* data_socket = mock_socket_factory_.GetMockTCPClientSocket(1);
736   ASSERT_TRUE(data_socket);
737   data_socket->Disconnect();
738 
739   // We should issue Reads until one returns EOF...
740   ASSERT_EQ(ERR_IO_PENDING,
741             transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
742 
743   // Make sure the transaction finishes cleanly.
744   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
745   EXPECT_EQ(OK, callback_.WaitForResult());
746   EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket.state());
747   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
748 }
749 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionTransferStarting)750 TEST_F(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
751   FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
752   ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
753 }
754 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionInvalidResponse)755 TEST_F(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
756   FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
757   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
758 }
759 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort1)760 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
761   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
762                                            FtpSocketDataProvider::PRE_QUIT);
763   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
764 }
765 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort2)766 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
767   // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
768   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
769                                            FtpSocketDataProvider::PRE_QUIT);
770   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
771 }
772 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort3)773 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
774   // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
775   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
776                                            FtpSocketDataProvider::PRE_QUIT);
777   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
778 }
779 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort4)780 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
781   // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
782   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
783                                            FtpSocketDataProvider::PRE_QUIT);
784   ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
785 }
786 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafeHost)787 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
788   FtpSocketDataProviderEvilPasv ctrl_socket(
789       "227 Portscan (10,1,2,3,4,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE);
790   std::string mock_data("mock-data");
791   MockRead data_reads[] = {
792     MockRead(mock_data.c_str()),
793   };
794   StaticSocketDataProvider data_socket1(data_reads, NULL);
795   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
796   mock_socket_factory_.AddSocketDataProvider(&data_socket1);
797   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
798 
799   // Start the transaction.
800   ASSERT_EQ(ERR_IO_PENDING,
801             transaction_.Start(&request_info, &callback_, NULL));
802   EXPECT_EQ(OK, callback_.WaitForResult());
803 
804   // The transaction fires the callback when we can start reading data. That
805   // means that the data socket should be open.
806   MockTCPClientSocket* data_socket =
807       mock_socket_factory_.GetMockTCPClientSocket(1);
808   ASSERT_TRUE(data_socket);
809   ASSERT_TRUE(data_socket->IsConnected());
810 
811   // Even if the PASV response specified some other address, we connect
812   // to the address we used for control connection.
813   EXPECT_EQ("127.0.0.1", NetAddressToString(data_socket->addresses().head()));
814 
815   // Make sure we have only one host entry in the AddressList.
816   EXPECT_FALSE(data_socket->addresses().head()->ai_next);
817 }
818 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadUsername)819 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
820   FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
821   ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
822 }
823 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadPassword)824 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
825   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
826   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
827 }
828 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionSpaceInLogin)829 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
830   FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
831   ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
832 }
833 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionSpaceInPassword)834 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
835   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
836   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
837 }
838 
TEST_F(FtpNetworkTransactionTest,EvilRestartUser)839 TEST_F(FtpNetworkTransactionTest, EvilRestartUser) {
840   FtpSocketDataProvider ctrl_socket1;
841   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
842                              FtpSocketDataProvider::PRE_QUIT,
843                              "530 Login authentication failed\r\n");
844   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
845 
846   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
847 
848   ASSERT_EQ(ERR_IO_PENDING,
849             transaction_.Start(&request_info, &callback_, NULL));
850   EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
851 
852   MockRead ctrl_reads[] = {
853     MockRead("220 host TestFTPd\r\n"),
854     MockRead("221 Goodbye!\r\n"),
855     MockRead(false, OK),
856   };
857   MockWrite ctrl_writes[] = {
858     MockWrite("QUIT\r\n"),
859   };
860   StaticSocketDataProvider ctrl_socket2(ctrl_reads, ctrl_writes);
861   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
862   ASSERT_EQ(ERR_IO_PENDING, transaction_.RestartWithAuth(L"foo\nownz0red",
863                                                          L"innocent",
864                                                          &callback_));
865   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
866 }
867 
TEST_F(FtpNetworkTransactionTest,EvilRestartPassword)868 TEST_F(FtpNetworkTransactionTest, EvilRestartPassword) {
869   FtpSocketDataProvider ctrl_socket1;
870   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
871                              FtpSocketDataProvider::PRE_QUIT,
872                              "530 Login authentication failed\r\n");
873   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
874 
875   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
876 
877   ASSERT_EQ(ERR_IO_PENDING,
878             transaction_.Start(&request_info, &callback_, NULL));
879   EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
880 
881   MockRead ctrl_reads[] = {
882     MockRead("220 host TestFTPd\r\n"),
883     MockRead("331 User okay, send password\r\n"),
884     MockRead("221 Goodbye!\r\n"),
885     MockRead(false, OK),
886   };
887   MockWrite ctrl_writes[] = {
888     MockWrite("USER innocent\r\n"),
889     MockWrite("QUIT\r\n"),
890   };
891   StaticSocketDataProvider ctrl_socket2(ctrl_reads, ctrl_writes);
892   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
893   ASSERT_EQ(ERR_IO_PENDING, transaction_.RestartWithAuth(L"innocent",
894                                                          L"foo\nownz0red",
895                                                          &callback_));
896   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
897 }
898 
TEST_F(FtpNetworkTransactionTest,Escaping)899 TEST_F(FtpNetworkTransactionTest, Escaping) {
900   FtpSocketDataProviderEscaping ctrl_socket;
901   ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
902                      OK);
903 }
904 
905 // Regression test for http://crbug.com/25023.
TEST_F(FtpNetworkTransactionTest,CloseConnection)906 TEST_F(FtpNetworkTransactionTest, CloseConnection) {
907   FtpSocketDataProviderCloseConnection ctrl_socket;
908   ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
909 }
910 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailUser)911 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
912   FtpSocketDataProviderDirectoryListing ctrl_socket;
913   TransactionFailHelper(&ctrl_socket,
914                         "ftp://host",
915                         FtpSocketDataProvider::PRE_USER,
916                         FtpSocketDataProvider::PRE_QUIT,
917                         "500 no such user\r\n",
918                         ERR_FAILED);
919 }
920 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPass)921 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
922   FtpSocketDataProviderDirectoryListing ctrl_socket;
923   TransactionFailHelper(&ctrl_socket,
924                         "ftp://host",
925                         FtpSocketDataProvider::PRE_PASSWD,
926                         FtpSocketDataProvider::PRE_QUIT,
927                         "530 Login authentication failed\r\n",
928                         ERR_FAILED);
929 }
930 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailSyst)931 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
932   FtpSocketDataProviderDirectoryListing ctrl_socket;
933   TransactionFailHelper(&ctrl_socket,
934                         "ftp://host",
935                         FtpSocketDataProvider::PRE_SYST,
936                         FtpSocketDataProvider::PRE_PWD,
937                         "500 failed syst\r\n",
938                         OK);
939 }
940 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPwd)941 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
942   FtpSocketDataProviderDirectoryListing ctrl_socket;
943   TransactionFailHelper(&ctrl_socket,
944                         "ftp://host",
945                         FtpSocketDataProvider::PRE_PWD,
946                         FtpSocketDataProvider::PRE_QUIT,
947                         "500 failed pwd\r\n",
948                         ERR_FAILED);
949 }
950 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailType)951 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
952   FtpSocketDataProviderDirectoryListing ctrl_socket;
953   TransactionFailHelper(&ctrl_socket,
954                         "ftp://host",
955                         FtpSocketDataProvider::PRE_TYPE,
956                         FtpSocketDataProvider::PRE_QUIT,
957                         "500 failed type\r\n",
958                         ERR_FAILED);
959 }
960 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPasv)961 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPasv) {
962   FtpSocketDataProviderDirectoryListing ctrl_socket;
963   TransactionFailHelper(&ctrl_socket,
964                         "ftp://host",
965                         FtpSocketDataProvider::PRE_PASV,
966                         FtpSocketDataProvider::PRE_QUIT,
967                         "500 failed pasv\r\n",
968                         ERR_FAILED);
969 }
970 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMalformedMdtm)971 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMalformedMdtm) {
972   FtpSocketDataProviderDirectoryListing ctrl_socket;
973   TransactionFailHelper(&ctrl_socket,
974                         "ftp://host",
975                         FtpSocketDataProvider::PRE_MDTM,
976                         FtpSocketDataProvider::PRE_RETR,
977                         "213 foobar\r\n",
978                         OK);
979 }
980 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailMdtm)981 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailMdtm) {
982   FtpSocketDataProviderDirectoryListing ctrl_socket;
983   TransactionFailHelper(&ctrl_socket,
984                         "ftp://host",
985                         FtpSocketDataProvider::PRE_MDTM,
986                         FtpSocketDataProvider::PRE_RETR,
987                         "500 failed mdtm\r\n",
988                         OK);
989 }
990 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPasv2)991 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPasv2) {
992   FtpSocketDataProviderDirectoryListing ctrl_socket;
993   TransactionFailHelper(&ctrl_socket,
994                         "ftp://host",
995                         FtpSocketDataProvider::PRE_PASV2,
996                         FtpSocketDataProvider::PRE_QUIT,
997                         "500 failed pasv2\r\n",
998                         ERR_FAILED);
999 }
1000 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailCwd)1001 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1002   FtpSocketDataProviderDirectoryListing ctrl_socket;
1003   TransactionFailHelper(&ctrl_socket,
1004                         "ftp://host",
1005                         FtpSocketDataProvider::PRE_CWD,
1006                         FtpSocketDataProvider::PRE_QUIT,
1007                         "500 failed cwd\r\n",
1008                         ERR_FAILED);
1009 }
1010 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFileNotFound)1011 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFileNotFound) {
1012   FtpSocketDataProviderDirectoryListing ctrl_socket;
1013   TransactionFailHelper(&ctrl_socket,
1014                         "ftp://host",
1015                         FtpSocketDataProvider::PRE_CWD,
1016                         FtpSocketDataProvider::PRE_QUIT,
1017                         "550 cannot open file\r\n",
1018                         ERR_FILE_NOT_FOUND);
1019 }
1020 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailMlsd)1021 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailMlsd) {
1022   FtpSocketDataProviderDirectoryListing ctrl_socket;
1023   TransactionFailHelper(&ctrl_socket,
1024                         "ftp://host",
1025                         FtpSocketDataProvider::PRE_MLSD,
1026                         FtpSocketDataProvider::PRE_LIST,
1027                         "500 Unrecognized command\r\n",
1028                         OK);
1029 }
1030 
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailList)1031 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1032   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1033   TransactionFailHelper(&ctrl_socket,
1034                         "ftp://host/dir",
1035                         FtpSocketDataProvider::PRE_LIST,
1036                         FtpSocketDataProvider::PRE_QUIT,
1037                         "500 failed list\r\n",
1038                         ERR_FAILED);
1039 }
1040 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailUser)1041 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1042   FtpSocketDataProviderFileDownload ctrl_socket;
1043   TransactionFailHelper(&ctrl_socket,
1044                         "ftp://host/file",
1045                         FtpSocketDataProvider::PRE_USER,
1046                         FtpSocketDataProvider::PRE_QUIT,
1047                         "500 no such user\r\n",
1048                         ERR_FAILED);
1049 }
1050 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPass)1051 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1052   FtpSocketDataProviderFileDownload ctrl_socket;
1053   TransactionFailHelper(&ctrl_socket,
1054                         "ftp://host/file",
1055                         FtpSocketDataProvider::PRE_PASSWD,
1056                         FtpSocketDataProvider::PRE_QUIT,
1057                         "530 Login authentication failed\r\n",
1058                         ERR_FAILED);
1059 }
1060 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailSyst)1061 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1062   FtpSocketDataProviderFileDownload ctrl_socket;
1063   TransactionFailHelper(&ctrl_socket,
1064                         "ftp://host/file",
1065                         FtpSocketDataProvider::PRE_SYST,
1066                         FtpSocketDataProvider::PRE_PWD,
1067                         "500 failed syst\r\n",
1068                         OK);
1069 }
1070 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPwd)1071 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1072   FtpSocketDataProviderFileDownload ctrl_socket;
1073   TransactionFailHelper(&ctrl_socket,
1074                         "ftp://host/file",
1075                         FtpSocketDataProvider::PRE_PWD,
1076                         FtpSocketDataProvider::PRE_QUIT,
1077                         "500 failed pwd\r\n",
1078                         ERR_FAILED);
1079 }
1080 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailType)1081 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1082   FtpSocketDataProviderFileDownload ctrl_socket;
1083   TransactionFailHelper(&ctrl_socket,
1084                         "ftp://host/file",
1085                         FtpSocketDataProvider::PRE_TYPE,
1086                         FtpSocketDataProvider::PRE_QUIT,
1087                         "500 failed type\r\n",
1088                         ERR_FAILED);
1089 }
1090 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPasv)1091 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPasv) {
1092   FtpSocketDataProviderFileDownload ctrl_socket;
1093   TransactionFailHelper(&ctrl_socket,
1094                         "ftp://host/file",
1095                         FtpSocketDataProvider::PRE_PASV,
1096                         FtpSocketDataProvider::PRE_QUIT,
1097                         "500 failed pasv\r\n",
1098                         ERR_FAILED);
1099 }
1100 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailMdtm)1101 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailMdtm) {
1102   FtpSocketDataProviderFileDownload ctrl_socket;
1103   TransactionFailHelper(&ctrl_socket,
1104                         "ftp://host/file",
1105                         FtpSocketDataProvider::PRE_MDTM,
1106                         FtpSocketDataProvider::PRE_RETR,
1107                         "500 failed mdtm\r\n",
1108                         OK);
1109 }
1110 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailRetr)1111 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1112   FtpSocketDataProviderFileDownloadRetrFail ctrl_socket;
1113   TransactionFailHelper(&ctrl_socket,
1114                         "ftp://host/file",
1115                         FtpSocketDataProvider::PRE_RETR,
1116                         FtpSocketDataProvider::PRE_QUIT,
1117                         "500 failed retr\r\n",
1118                         ERR_FAILED);
1119 }
1120 
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFileNotFound)1121 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFileNotFound) {
1122   FtpSocketDataProviderFileDownloadRetrFail ctrl_socket;
1123   TransactionFailHelper(&ctrl_socket,
1124                         "ftp://host/file",
1125                         FtpSocketDataProvider::PRE_RETR,
1126                         FtpSocketDataProvider::PRE_PASV2,
1127                         "550 cannot open file\r\n",
1128                         ERR_FILE_NOT_FOUND);
1129 }
1130 
1131 }  // namespace net
1132