• 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 #include "net/ftp/ftp_network_transaction.h"
6 
7 #include "build/build_config.h"
8 
9 #include "base/compiler_specific.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_util.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/ftp/ftp_network_session.h"
20 #include "net/ftp/ftp_request_info.h"
21 #include "net/socket/socket_test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h"
24 
25 namespace {
26 
27 // Size we use for IOBuffers used to receive data from the test data socket.
28 const int kBufferSize = 128;
29 
30 }  // namespace
31 
32 namespace net {
33 
34 class FtpSocketDataProvider : public DynamicSocketDataProvider {
35  public:
36   enum State {
37     NONE,
38     PRE_USER,
39     PRE_PASSWD,
40     PRE_SYST,
41     PRE_PWD,
42     PRE_TYPE,
43     PRE_SIZE,
44     PRE_EPSV,
45     PRE_PASV,
46     PRE_LIST,
47     PRE_RETR,
48     PRE_RETR_EPSV,
49     PRE_RETR_PASV,
50     PRE_CWD_EPSV,
51     PRE_CWD_PASV,
52     PRE_CWD,
53     PRE_QUIT,
54     PRE_NOPASV,
55     QUIT
56   };
57 
FtpSocketDataProvider()58   FtpSocketDataProvider()
59       : failure_injection_state_(NONE),
60         multiline_welcome_(false),
61         use_epsv_(true),
62         data_type_('I') {
63     Init();
64   }
65 
OnWrite(const std::string & data)66   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
67     if (InjectFault())
68       return MockWriteResult(ASYNC, data.length());
69     switch (state()) {
70       case PRE_USER:
71         return Verify("USER anonymous\r\n", data, PRE_PASSWD,
72                       "331 Password needed\r\n");
73       case PRE_PASSWD:
74         {
75           const char* response_one = "230 Welcome\r\n";
76           const char* response_multi = "230- One\r\n230- Two\r\n230 Three\r\n";
77           return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
78                         multiline_welcome_ ? response_multi : response_one);
79         }
80       case PRE_SYST:
81         return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
82       case PRE_PWD:
83         return Verify("PWD\r\n", data, PRE_TYPE,
84                       "257 \"/\" is your current location\r\n");
85       case PRE_TYPE:
86         return Verify(std::string("TYPE ") + data_type_ + "\r\n", data,
87                       use_epsv_ ? PRE_EPSV : PRE_PASV,
88                       "200 TYPE set successfully\r\n");
89       case PRE_EPSV:
90         return Verify("EPSV\r\n", data, PRE_SIZE,
91                       "227 Entering Extended Passive Mode (|||31744|)\r\n");
92       case PRE_CWD_EPSV:
93         return Verify("EPSV\r\n", data, PRE_CWD,
94                       "227 Entering Extended Passive Mode (|||31744|)\r\n");
95       case PRE_RETR_EPSV:
96         return Verify("EPSV\r\n", data, PRE_RETR,
97                       "227 Entering Extended Passive Mode (|||31744|)\r\n");
98       case PRE_CWD_PASV:
99         return Verify("PASV\r\n", data, PRE_CWD,
100                       "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
101       case PRE_RETR_PASV:
102         return Verify("PASV\r\n", data, PRE_RETR,
103                       "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
104       case PRE_PASV:
105         return Verify("PASV\r\n", data, PRE_SIZE,
106                       "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
107       case PRE_NOPASV:
108         // Use unallocated 599 FTP error code to make sure it falls into the
109         // generic ERR_FTP_FAILED bucket.
110         return Verify("PASV\r\n", data, PRE_QUIT,
111                       "599 fail\r\n");
112       case PRE_QUIT:
113         return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
114       default:
115         NOTREACHED() << "State not handled " << state();
116         return MockWriteResult(ASYNC, ERR_UNEXPECTED);
117     }
118   }
119 
InjectFailure(State state,State next_state,const char * response)120   void InjectFailure(State state, State next_state, const char* response) {
121     DCHECK_EQ(NONE, failure_injection_state_);
122     DCHECK_NE(NONE, state);
123     DCHECK_NE(NONE, next_state);
124     DCHECK_NE(state, next_state);
125     failure_injection_state_ = state;
126     failure_injection_next_state_ = next_state;
127     fault_response_ = response;
128   }
129 
state() const130   State state() const {
131     return state_;
132   }
133 
Reset()134   virtual void Reset() OVERRIDE {
135     DynamicSocketDataProvider::Reset();
136     Init();
137   }
138 
set_multiline_welcome(bool multiline)139   void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; }
140 
use_epsv() const141   bool use_epsv() const { return use_epsv_; }
set_use_epsv(bool use_epsv)142   void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; }
143 
set_data_type(char data_type)144   void set_data_type(char data_type) { data_type_ = data_type; }
145 
146  protected:
Init()147   void Init() {
148     state_ = PRE_USER;
149     SimulateRead("220 host TestFTPd\r\n");
150   }
151 
152   // If protocol fault injection has been requested, adjusts state and mocked
153   // read and returns true.
InjectFault()154   bool InjectFault() {
155     if (state_ != failure_injection_state_)
156       return false;
157     SimulateRead(fault_response_);
158     state_ = failure_injection_next_state_;
159     return true;
160   }
161 
Verify(const std::string & expected,const std::string & data,State next_state,const char * next_read,const size_t next_read_length)162   MockWriteResult Verify(const std::string& expected,
163                          const std::string& data,
164                          State next_state,
165                          const char* next_read,
166                          const size_t next_read_length) {
167     EXPECT_EQ(expected, data);
168     if (expected == data) {
169       state_ = next_state;
170       SimulateRead(next_read, next_read_length);
171       return MockWriteResult(ASYNC, data.length());
172     }
173     return MockWriteResult(ASYNC, ERR_UNEXPECTED);
174   }
175 
Verify(const std::string & expected,const std::string & data,State next_state,const char * next_read)176   MockWriteResult Verify(const std::string& expected,
177                          const std::string& data,
178                          State next_state,
179                          const char* next_read) {
180     return Verify(expected, data, next_state,
181                   next_read, std::strlen(next_read));
182   }
183 
184 
185  private:
186   State state_;
187   State failure_injection_state_;
188   State failure_injection_next_state_;
189   const char* fault_response_;
190 
191   // If true, we will send multiple 230 lines as response after PASS.
192   bool multiline_welcome_;
193 
194   // If true, we will use EPSV command.
195   bool use_epsv_;
196 
197   // Data type to be used for TYPE command.
198   char data_type_;
199 
200   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
201 };
202 
203 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
204  public:
FtpSocketDataProviderDirectoryListing()205   FtpSocketDataProviderDirectoryListing() {
206   }
207 
OnWrite(const std::string & data)208   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
209     if (InjectFault())
210       return MockWriteResult(ASYNC, data.length());
211     switch (state()) {
212       case PRE_SIZE:
213         return Verify("SIZE /\r\n", data,
214                       use_epsv() ? PRE_CWD_EPSV : PRE_CWD_PASV,
215                       "550 I can only retrieve regular files\r\n");
216       case PRE_CWD:
217         return Verify("CWD /\r\n", data, PRE_LIST, "200 OK\r\n");
218       case PRE_LIST:
219         return Verify("LIST -l\r\n", data, PRE_QUIT, "200 OK\r\n");
220       default:
221         return FtpSocketDataProvider::OnWrite(data);
222     }
223   }
224 
225  private:
226   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
227 };
228 
229 class FtpSocketDataProviderDirectoryListingWithPasvFallback
230     : public FtpSocketDataProviderDirectoryListing {
231  public:
FtpSocketDataProviderDirectoryListingWithPasvFallback()232   FtpSocketDataProviderDirectoryListingWithPasvFallback() {
233   }
234 
OnWrite(const std::string & data)235   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
236     if (InjectFault())
237       return MockWriteResult(ASYNC, data.length());
238     switch (state()) {
239       case PRE_EPSV:
240         return Verify("EPSV\r\n", data, PRE_PASV,
241                       "500 no EPSV for you\r\n");
242       case PRE_SIZE:
243         return Verify("SIZE /\r\n", data, PRE_CWD_PASV,
244                       "550 I can only retrieve regular files\r\n");
245       default:
246         return FtpSocketDataProviderDirectoryListing::OnWrite(data);
247     }
248   }
249 
250  private:
251   DISALLOW_COPY_AND_ASSIGN(
252       FtpSocketDataProviderDirectoryListingWithPasvFallback);
253 };
254 
255 class FtpSocketDataProviderDirectoryListingZeroSize
256     : public FtpSocketDataProviderDirectoryListing {
257  public:
FtpSocketDataProviderDirectoryListingZeroSize()258   FtpSocketDataProviderDirectoryListingZeroSize() {
259   }
260 
OnWrite(const std::string & data)261   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
262     if (InjectFault())
263       return MockWriteResult(ASYNC, data.length());
264     switch (state()) {
265       case PRE_SIZE:
266         return Verify("SIZE /\r\n", data, PRE_CWD, "213 0\r\n");
267       default:
268         return FtpSocketDataProviderDirectoryListing::OnWrite(data);
269     }
270   }
271 
272  private:
273   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize);
274 };
275 
276 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
277  public:
FtpSocketDataProviderVMSDirectoryListing()278   FtpSocketDataProviderVMSDirectoryListing() {
279   }
280 
OnWrite(const std::string & data)281   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
282     if (InjectFault())
283       return MockWriteResult(ASYNC, data.length());
284     switch (state()) {
285       case PRE_SYST:
286         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
287       case PRE_PWD:
288         return Verify("PWD\r\n", data, PRE_TYPE,
289                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
290       case PRE_EPSV:
291         return Verify("EPSV\r\n", data, PRE_PASV, "500 Invalid command\r\n");
292       case PRE_SIZE:
293         return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_CWD_PASV,
294                       "550 I can only retrieve regular files\r\n");
295       case PRE_CWD:
296         return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data, PRE_LIST,
297                       "200 OK\r\n");
298       case PRE_LIST:
299         return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
300       default:
301         return FtpSocketDataProvider::OnWrite(data);
302     }
303   }
304 
305  private:
306   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
307 };
308 
309 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
310     : public FtpSocketDataProvider {
311  public:
FtpSocketDataProviderVMSDirectoryListingRootDirectory()312   FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
313   }
314 
OnWrite(const std::string & data)315   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
316     if (InjectFault())
317       return MockWriteResult(ASYNC, data.length());
318     switch (state()) {
319       case PRE_SYST:
320         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
321       case PRE_PWD:
322         return Verify("PWD\r\n", data, PRE_TYPE,
323                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
324       case PRE_EPSV:
325         return Verify("EPSV\r\n", data, PRE_PASV,
326                       "500 EPSV command unknown\r\n");
327       case PRE_SIZE:
328         return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_CWD_PASV,
329                       "550 I can only retrieve regular files\r\n");
330       case PRE_CWD:
331         return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data, PRE_LIST,
332                       "200 OK\r\n");
333       case PRE_LIST:
334         return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
335       default:
336         return FtpSocketDataProvider::OnWrite(data);
337     }
338   }
339 
340  private:
341   DISALLOW_COPY_AND_ASSIGN(
342       FtpSocketDataProviderVMSDirectoryListingRootDirectory);
343 };
344 
345 class FtpSocketDataProviderFileDownloadWithFileTypecode
346     : public FtpSocketDataProvider {
347  public:
FtpSocketDataProviderFileDownloadWithFileTypecode()348   FtpSocketDataProviderFileDownloadWithFileTypecode() {
349   }
350 
OnWrite(const std::string & data)351   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
352     if (InjectFault())
353       return MockWriteResult(ASYNC, data.length());
354     switch (state()) {
355       case PRE_SIZE:
356         return Verify("SIZE /file\r\n", data, PRE_RETR,
357                       "213 18\r\n");
358       case PRE_RETR:
359         return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
360       default:
361         return FtpSocketDataProvider::OnWrite(data);
362     }
363   }
364 
365  private:
366   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode);
367 };
368 
369 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
370  public:
FtpSocketDataProviderFileDownload()371   FtpSocketDataProviderFileDownload() {
372   }
373 
OnWrite(const std::string & data)374   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
375     if (InjectFault())
376       return MockWriteResult(ASYNC, data.length());
377     switch (state()) {
378       case PRE_SIZE:
379         return Verify("SIZE /file\r\n", data, PRE_CWD,
380                       "213 18\r\n");
381       case PRE_CWD:
382         return Verify("CWD /file\r\n", data,
383                       use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
384                       "550 Not a directory\r\n");
385       case PRE_RETR:
386         return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
387       default:
388         return FtpSocketDataProvider::OnWrite(data);
389     }
390   }
391 
392  private:
393   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
394 };
395 
396 class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider {
397  public:
FtpSocketDataProviderFileNotFound()398   FtpSocketDataProviderFileNotFound() {
399   }
400 
OnWrite(const std::string & data)401   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
402     if (InjectFault())
403       return MockWriteResult(ASYNC, data.length());
404     switch (state()) {
405       case PRE_SIZE:
406         return Verify("SIZE /file\r\n", data,
407                       use_epsv() ? PRE_CWD_EPSV : PRE_CWD_PASV,
408                       "550 File Not Found\r\n");
409       case PRE_CWD:
410         return Verify("CWD /file\r\n", data,
411                       use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
412                       "550 File Not Found\r\n");
413       case PRE_RETR:
414         return Verify("RETR /file\r\n", data, PRE_QUIT,
415                       "550 File Not Found\r\n");
416       default:
417         return FtpSocketDataProvider::OnWrite(data);
418     }
419   }
420 
421  private:
422   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound);
423 };
424 
425 class FtpSocketDataProviderFileDownloadWithPasvFallback
426     : public FtpSocketDataProviderFileDownload {
427  public:
FtpSocketDataProviderFileDownloadWithPasvFallback()428   FtpSocketDataProviderFileDownloadWithPasvFallback() {
429   }
430 
OnWrite(const std::string & data)431   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
432     if (InjectFault())
433       return MockWriteResult(ASYNC, data.length());
434     switch (state()) {
435       case PRE_EPSV:
436         return Verify("EPSV\r\n", data, PRE_PASV,
437                       "500 No can do\r\n");
438       case PRE_CWD:
439         return Verify("CWD /file\r\n", data, PRE_RETR_PASV,
440                       "550 Not a directory\r\n");
441       default:
442         return FtpSocketDataProviderFileDownload::OnWrite(data);
443     }
444   }
445 
446  private:
447   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback);
448 };
449 
450 class FtpSocketDataProviderFileDownloadZeroSize
451     : public FtpSocketDataProviderFileDownload {
452  public:
FtpSocketDataProviderFileDownloadZeroSize()453   FtpSocketDataProviderFileDownloadZeroSize() {
454   }
455 
OnWrite(const std::string & data)456   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
457     if (InjectFault())
458       return MockWriteResult(ASYNC, data.length());
459     switch (state()) {
460       case PRE_SIZE:
461         return Verify("SIZE /file\r\n", data, PRE_CWD,
462                       "213 0\r\n");
463       case PRE_CWD:
464         return Verify("CWD /file\r\n", data,
465                       use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
466                       "550 not a directory\r\n");
467       default:
468         return FtpSocketDataProviderFileDownload::OnWrite(data);
469     }
470   }
471 
472  private:
473   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize);
474 };
475 
476 class FtpSocketDataProviderFileDownloadCWD451
477     : public FtpSocketDataProviderFileDownload {
478  public:
FtpSocketDataProviderFileDownloadCWD451()479   FtpSocketDataProviderFileDownloadCWD451() {
480   }
481 
OnWrite(const std::string & data)482   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
483     if (InjectFault())
484       return MockWriteResult(ASYNC, data.length());
485     switch (state()) {
486       case PRE_CWD:
487         return Verify("CWD /file\r\n", data,
488                       use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
489                       "451 not a directory\r\n");
490       default:
491         return FtpSocketDataProviderFileDownload::OnWrite(data);
492     }
493   }
494 
495  private:
496   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451);
497 };
498 
499 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
500  public:
FtpSocketDataProviderVMSFileDownload()501   FtpSocketDataProviderVMSFileDownload() {
502   }
503 
OnWrite(const std::string & data)504   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
505     if (InjectFault())
506       return MockWriteResult(ASYNC, data.length());
507     switch (state()) {
508       case PRE_SYST:
509         return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
510       case PRE_PWD:
511         return Verify("PWD\r\n", data, PRE_TYPE,
512                       "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
513       case PRE_EPSV:
514         return Verify("EPSV\r\n", data, PRE_PASV,
515                       "500 EPSV command unknown\r\n");
516       case PRE_SIZE:
517         return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD,
518                       "213 18\r\n");
519       case PRE_CWD:
520         return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data, PRE_RETR_PASV,
521                       "550 Not a directory\r\n");
522       case PRE_RETR:
523         return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
524                       "200 OK\r\n");
525       default:
526         return FtpSocketDataProvider::OnWrite(data);
527     }
528   }
529 
530  private:
531   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
532 };
533 
534 class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload {
535  public:
FtpSocketDataProviderEscaping()536   FtpSocketDataProviderEscaping() {
537   }
538 
OnWrite(const std::string & data)539   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
540     if (InjectFault())
541       return MockWriteResult(ASYNC, data.length());
542     switch (state()) {
543       case PRE_SIZE:
544         return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD,
545                       "213 18\r\n");
546       case PRE_CWD:
547         return Verify("CWD / !\"#$%y\200\201\r\n", data,
548                       use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
549                       "550 Not a directory\r\n");
550       case PRE_RETR:
551         return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
552                       "200 OK\r\n");
553       default:
554         return FtpSocketDataProviderFileDownload::OnWrite(data);
555     }
556   }
557 
558  private:
559   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
560 };
561 
562 class FtpSocketDataProviderFileDownloadTransferStarting
563     : public FtpSocketDataProviderFileDownload {
564  public:
FtpSocketDataProviderFileDownloadTransferStarting()565   FtpSocketDataProviderFileDownloadTransferStarting() {
566   }
567 
OnWrite(const std::string & data)568   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
569     if (InjectFault())
570       return MockWriteResult(ASYNC, data.length());
571     switch (state()) {
572       case PRE_RETR:
573         return Verify("RETR /file\r\n", data, PRE_QUIT,
574                       "125-Data connection already open.\r\n"
575                       "125  Transfer starting.\r\n"
576                       "226 Transfer complete.\r\n");
577       default:
578         return FtpSocketDataProviderFileDownload::OnWrite(data);
579     }
580   }
581 
582  private:
583   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
584 };
585 
586 class FtpSocketDataProviderDirectoryListingTransferStarting
587     : public FtpSocketDataProviderDirectoryListing {
588  public:
FtpSocketDataProviderDirectoryListingTransferStarting()589   FtpSocketDataProviderDirectoryListingTransferStarting() {
590   }
591 
OnWrite(const std::string & data)592   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
593     if (InjectFault())
594       return MockWriteResult(ASYNC, data.length());
595     switch (state()) {
596       case PRE_LIST:
597         return Verify("LIST -l\r\n", data, PRE_QUIT,
598                       "125-Data connection already open.\r\n"
599                       "125  Transfer starting.\r\n"
600                       "226 Transfer complete.\r\n");
601       default:
602         return FtpSocketDataProviderDirectoryListing::OnWrite(data);
603     }
604   }
605 
606  private:
607   DISALLOW_COPY_AND_ASSIGN(
608       FtpSocketDataProviderDirectoryListingTransferStarting);
609 };
610 
611 class FtpSocketDataProviderFileDownloadInvalidResponse
612     : public FtpSocketDataProviderFileDownload {
613  public:
FtpSocketDataProviderFileDownloadInvalidResponse()614   FtpSocketDataProviderFileDownloadInvalidResponse() {
615   }
616 
OnWrite(const std::string & data)617   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
618     if (InjectFault())
619       return MockWriteResult(ASYNC, data.length());
620     switch (state()) {
621       case PRE_SIZE:
622         // Use unallocated 599 FTP error code to make sure it falls into the
623         // generic ERR_FTP_FAILED bucket.
624         return Verify("SIZE /file\r\n", data, PRE_QUIT,
625                       "599 Evil Response\r\n"
626                       "599 More Evil\r\n");
627       default:
628         return FtpSocketDataProviderFileDownload::OnWrite(data);
629     }
630   }
631 
632  private:
633   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
634 };
635 
636 class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload {
637  public:
FtpSocketDataProviderEvilEpsv(const char * epsv_response,State expected_state)638   FtpSocketDataProviderEvilEpsv(const char* epsv_response,
639                                 State expected_state)
640       : epsv_response_(epsv_response),
641         epsv_response_length_(std::strlen(epsv_response)),
642         expected_state_(expected_state) {}
643 
FtpSocketDataProviderEvilEpsv(const char * epsv_response,size_t epsv_response_length,State expected_state)644   FtpSocketDataProviderEvilEpsv(const char* epsv_response,
645                                size_t epsv_response_length,
646                                State expected_state)
647       : epsv_response_(epsv_response),
648         epsv_response_length_(epsv_response_length),
649         expected_state_(expected_state) {}
650 
OnWrite(const std::string & data)651   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
652     if (InjectFault())
653       return MockWriteResult(ASYNC, data.length());
654     switch (state()) {
655       case PRE_EPSV:
656         return Verify("EPSV\r\n", data, expected_state_,
657                       epsv_response_, epsv_response_length_);
658       default:
659         return FtpSocketDataProviderFileDownload::OnWrite(data);
660     }
661   }
662 
663  private:
664   const char* epsv_response_;
665   const size_t epsv_response_length_;
666   const State expected_state_;
667 
668   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv);
669 };
670 
671 class FtpSocketDataProviderEvilPasv
672     : public FtpSocketDataProviderFileDownloadWithPasvFallback {
673  public:
FtpSocketDataProviderEvilPasv(const char * pasv_response,State expected_state)674   FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state)
675       : pasv_response_(pasv_response),
676         expected_state_(expected_state) {
677   }
678 
OnWrite(const std::string & data)679   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
680     if (InjectFault())
681       return MockWriteResult(ASYNC, data.length());
682     switch (state()) {
683       case PRE_PASV:
684         return Verify("PASV\r\n", data, expected_state_, pasv_response_);
685       default:
686         return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data);
687     }
688   }
689 
690  private:
691   const char* pasv_response_;
692   const State expected_state_;
693 
694   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
695 };
696 
697 class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload {
698  public:
FtpSocketDataProviderEvilSize(const char * size_response,State expected_state)699   FtpSocketDataProviderEvilSize(const char* size_response, State expected_state)
700       : size_response_(size_response),
701         expected_state_(expected_state) {
702   }
703 
OnWrite(const std::string & data)704   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
705     if (InjectFault())
706       return MockWriteResult(ASYNC, data.length());
707     switch (state()) {
708       case PRE_SIZE:
709         return Verify("SIZE /file\r\n", data, expected_state_, size_response_);
710       default:
711         return FtpSocketDataProviderFileDownload::OnWrite(data);
712     }
713   }
714 
715  private:
716   const char* size_response_;
717   const State expected_state_;
718 
719   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize);
720 };
721 
722 class FtpSocketDataProviderEvilLogin
723     : public FtpSocketDataProviderFileDownload {
724  public:
FtpSocketDataProviderEvilLogin(const char * expected_user,const char * expected_password)725   FtpSocketDataProviderEvilLogin(const char* expected_user,
726                                 const char* expected_password)
727       : expected_user_(expected_user),
728         expected_password_(expected_password) {
729   }
730 
OnWrite(const std::string & data)731   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
732     if (InjectFault())
733       return MockWriteResult(ASYNC, data.length());
734     switch (state()) {
735       case PRE_USER:
736         return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
737                       PRE_PASSWD, "331 Password needed\r\n");
738       case PRE_PASSWD:
739         return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
740                       PRE_SYST, "230 Welcome\r\n");
741       default:
742         return FtpSocketDataProviderFileDownload::OnWrite(data);
743     }
744   }
745 
746  private:
747   const char* expected_user_;
748   const char* expected_password_;
749 
750   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
751 };
752 
753 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
754  public:
FtpSocketDataProviderCloseConnection()755   FtpSocketDataProviderCloseConnection() {
756   }
757 
OnWrite(const std::string & data)758   virtual MockWriteResult OnWrite(const std::string& data) OVERRIDE {
759     if (InjectFault())
760       return MockWriteResult(ASYNC, data.length());
761     switch (state()) {
762       case PRE_USER:
763         return Verify("USER anonymous\r\n", data,
764                       PRE_QUIT, "");
765       default:
766         return FtpSocketDataProvider::OnWrite(data);
767     }
768   }
769 
770  private:
771   DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
772 };
773 
774 class FtpNetworkTransactionTest
775     : public PlatformTest,
776       public ::testing::WithParamInterface<int> {
777  public:
FtpNetworkTransactionTest()778   FtpNetworkTransactionTest()
779       : host_resolver_(new MockHostResolver),
780         session_(new FtpNetworkSession(host_resolver_.get())),
781         transaction_(session_.get(), &mock_socket_factory_) {
782     scoped_refptr<RuleBasedHostResolverProc> rules(
783         new RuleBasedHostResolverProc(NULL));
784     if (GetFamily() == AF_INET) {
785       rules->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
786     } else if (GetFamily() == AF_INET6) {
787       rules->AddIPLiteralRule("*", "::1", "::1");
788     } else {
789       NOTREACHED();
790     }
791     host_resolver_->set_rules(rules.get());
792   }
793 
794  protected:
795   // Accessor to make code refactoring-friendly, e.g. when we change the way
796   // parameters are passed (like more parameters).
GetFamily()797   int GetFamily() {
798     return GetParam();
799   }
800 
GetRequestInfo(const std::string & url)801   FtpRequestInfo GetRequestInfo(const std::string& url) {
802     FtpRequestInfo info;
803     info.url = GURL(url);
804     return info;
805   }
806 
ExecuteTransaction(FtpSocketDataProvider * ctrl_socket,const char * request,int data_socket,int expected_result)807   void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
808                           const char* request,
809                           int data_socket,
810                           int expected_result) {
811     // Expect EPSV usage for non-IPv4 control connections.
812     ctrl_socket->set_use_epsv((GetFamily() != AF_INET));
813 
814     mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
815 
816     std::string mock_data("mock-data");
817     MockRead data_reads[] = {
818       // Usually FTP servers close the data connection after the entire data has
819       // been received.
820       MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
821       MockRead(mock_data.c_str()),
822     };
823 
824     ScopedVector<StaticSocketDataProvider> data_sockets;
825     data_sockets.reserve(data_socket);
826     for (int i = 0; i < data_socket + 1; i++) {
827       // We only read from one data socket, other ones are dummy.
828       if (i == data_socket) {
829         data_sockets.push_back(new StaticSocketDataProvider(
830                                    data_reads, arraysize(data_reads), NULL, 0));
831       } else {
832         data_sockets.push_back(new StaticSocketDataProvider);
833       }
834       mock_socket_factory_.AddSocketDataProvider(data_sockets[i]);
835     }
836 
837     FtpRequestInfo request_info = GetRequestInfo(request);
838     EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
839     ASSERT_EQ(ERR_IO_PENDING,
840               transaction_.Start(&request_info, callback_.callback(),
841                                  BoundNetLog()));
842     EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
843     ASSERT_EQ(expected_result, callback_.WaitForResult());
844     if (expected_result == OK) {
845       scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
846       memset(io_buffer->data(), 0, kBufferSize);
847       ASSERT_EQ(ERR_IO_PENDING,
848                 transaction_.Read(io_buffer.get(), kBufferSize,
849                                   callback_.callback()));
850       ASSERT_EQ(static_cast<int>(mock_data.length()),
851                 callback_.WaitForResult());
852       EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
853 
854       // Do another Read to detect that the data socket is now closed.
855       int rv = transaction_.Read(io_buffer.get(), kBufferSize,
856                                  callback_.callback());
857       if (rv == ERR_IO_PENDING) {
858         EXPECT_EQ(0, callback_.WaitForResult());
859       } else {
860         EXPECT_EQ(0, rv);
861       }
862     }
863     EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
864     EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
865   }
866 
TransactionFailHelper(FtpSocketDataProvider * ctrl_socket,const char * request,FtpSocketDataProvider::State state,FtpSocketDataProvider::State next_state,const char * response,int expected_result)867   void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
868                              const char* request,
869                              FtpSocketDataProvider::State state,
870                              FtpSocketDataProvider::State next_state,
871                              const char* response,
872                              int expected_result) {
873     ctrl_socket->InjectFailure(state, next_state, response);
874     ExecuteTransaction(ctrl_socket, request, 1, expected_result);
875   }
876 
877   scoped_ptr<MockHostResolver> host_resolver_;
878   scoped_refptr<FtpNetworkSession> session_;
879   MockClientSocketFactory mock_socket_factory_;
880   FtpNetworkTransaction transaction_;
881   TestCompletionCallback callback_;
882 };
883 
TEST_P(FtpNetworkTransactionTest,FailedLookup)884 TEST_P(FtpNetworkTransactionTest, FailedLookup) {
885   FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
886   scoped_refptr<RuleBasedHostResolverProc> rules(
887       new RuleBasedHostResolverProc(NULL));
888   rules->AddSimulatedFailure("badhost");
889   host_resolver_->set_rules(rules.get());
890 
891   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
892   ASSERT_EQ(ERR_IO_PENDING,
893             transaction_.Start(&request_info, callback_.callback(),
894                                BoundNetLog()));
895   ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
896   EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
897 }
898 
899 // Check that when determining the host, the square brackets decorating IPv6
900 // literals in URLs are stripped.
TEST_P(FtpNetworkTransactionTest,StripBracketsFromIPv6Literals)901 TEST_P(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) {
902   // This test only makes sense for IPv6 connections.
903   if (GetFamily() != AF_INET6)
904     return;
905 
906   host_resolver_->rules()->AddSimulatedFailure("[::1]");
907 
908   // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
909   // The important part of this test is to make sure that we don't fail with
910   // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
911   // was used.
912   FtpSocketDataProviderEvilSize ctrl_socket(
913       "213 99999999999999999999999999999999\r\n",
914       FtpSocketDataProvider::PRE_QUIT);
915   ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", 1, ERR_INVALID_RESPONSE);
916 }
917 
TEST_P(FtpNetworkTransactionTest,DirectoryTransaction)918 TEST_P(FtpNetworkTransactionTest, DirectoryTransaction) {
919   FtpSocketDataProviderDirectoryListing ctrl_socket;
920   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
921 
922   EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
923   EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
924   EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
925             transaction_.GetResponseInfo()->socket_address.host());
926   EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
927 }
928 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionWithPasvFallback)929 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) {
930   FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket;
931   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
932 
933   EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
934   EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
935 }
936 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionWithTypecode)937 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) {
938   FtpSocketDataProviderDirectoryListing ctrl_socket;
939   ExecuteTransaction(&ctrl_socket, "ftp://host;type=d", 1, OK);
940 
941   EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
942   EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
943 }
944 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcome)945 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
946   FtpSocketDataProviderDirectoryListing ctrl_socket;
947   ctrl_socket.set_multiline_welcome(true);
948   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
949 }
950 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionShortReads2)951 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
952   FtpSocketDataProviderDirectoryListing ctrl_socket;
953   ctrl_socket.set_short_read_limit(2);
954   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
955 }
956 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionShortReads5)957 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
958   FtpSocketDataProviderDirectoryListing ctrl_socket;
959   ctrl_socket.set_short_read_limit(5);
960   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
961 }
962 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcomeShort)963 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
964   FtpSocketDataProviderDirectoryListing ctrl_socket;
965   // The client will not consume all three 230 lines. That's good, we want to
966   // test that scenario.
967   ctrl_socket.allow_unconsumed_reads(true);
968   ctrl_socket.set_multiline_welcome(true);
969   ctrl_socket.set_short_read_limit(5);
970   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
971 }
972 
973 // Regression test for http://crbug.com/60555.
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionZeroSize)974 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
975   FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
976   ExecuteTransaction(&ctrl_socket, "ftp://host", 0, OK);
977 }
978 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionVMS)979 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
980   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
981   ExecuteTransaction(&ctrl_socket, "ftp://host/dir", 1, OK);
982 }
983 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionVMSRootDirectory)984 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
985   FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
986   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
987 }
988 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionTransferStarting)989 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
990   FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
991   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
992 }
993 
TEST_P(FtpNetworkTransactionTest,DownloadTransaction)994 TEST_P(FtpNetworkTransactionTest, DownloadTransaction) {
995   FtpSocketDataProviderFileDownload ctrl_socket;
996   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
997 
998   // We pass an artificial value of 18 as a response to the SIZE command.
999   EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1000   EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
1001             transaction_.GetResponseInfo()->socket_address.host());
1002   EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
1003 }
1004 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionWithPasvFallback)1005 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) {
1006   FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket;
1007   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1008 
1009   // We pass an artificial value of 18 as a response to the SIZE command.
1010   EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1011 }
1012 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionWithTypecodeA)1013 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) {
1014   FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1015   ctrl_socket.set_data_type('A');
1016   ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", 0, OK);
1017 
1018   // We pass an artificial value of 18 as a response to the SIZE command.
1019   EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1020 }
1021 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionWithTypecodeI)1022 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) {
1023   FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1024   ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", 0, OK);
1025 
1026   // We pass an artificial value of 18 as a response to the SIZE command.
1027   EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1028 }
1029 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionMultilineWelcome)1030 TEST_P(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
1031   FtpSocketDataProviderFileDownload ctrl_socket;
1032   ctrl_socket.set_multiline_welcome(true);
1033   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1034 }
1035 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionShortReads2)1036 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
1037   FtpSocketDataProviderFileDownload ctrl_socket;
1038   ctrl_socket.set_short_read_limit(2);
1039   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1040 }
1041 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionShortReads5)1042 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
1043   FtpSocketDataProviderFileDownload ctrl_socket;
1044   ctrl_socket.set_short_read_limit(5);
1045   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1046 }
1047 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionZeroSize)1048 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
1049   FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
1050   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1051 }
1052 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionCWD451)1053 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) {
1054   FtpSocketDataProviderFileDownloadCWD451 ctrl_socket;
1055   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1056 }
1057 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionVMS)1058 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) {
1059   FtpSocketDataProviderVMSFileDownload ctrl_socket;
1060   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1061 }
1062 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionTransferStarting)1063 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
1064   FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
1065   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1066 }
1067 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionInvalidResponse)1068 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
1069   FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
1070   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1071 }
1072 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvReallyBadFormat)1073 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) {
1074   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n",
1075                                             FtpSocketDataProvider::PRE_QUIT);
1076   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1077 }
1078 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort1)1079 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
1080   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1081                                             FtpSocketDataProvider::PRE_QUIT);
1082   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1083 }
1084 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort2)1085 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
1086   // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1087   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1088                                             FtpSocketDataProvider::PRE_QUIT);
1089   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1090 }
1091 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort3)1092 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
1093   // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1094   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1095                                             FtpSocketDataProvider::PRE_QUIT);
1096   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1097 }
1098 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort4)1099 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
1100   // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1101   FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1102                                             FtpSocketDataProvider::PRE_QUIT);
1103   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1104 }
1105 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafeHost)1106 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
1107   FtpSocketDataProviderEvilPasv ctrl_socket(
1108       "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE);
1109   ctrl_socket.set_use_epsv(GetFamily() != AF_INET);
1110   std::string mock_data("mock-data");
1111   MockRead data_reads[] = {
1112     MockRead(mock_data.c_str()),
1113   };
1114   StaticSocketDataProvider data_socket1;
1115   StaticSocketDataProvider data_socket2(data_reads, arraysize(data_reads),
1116                                         NULL, 0);
1117   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
1118   mock_socket_factory_.AddSocketDataProvider(&data_socket1);
1119   mock_socket_factory_.AddSocketDataProvider(&data_socket2);
1120   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1121 
1122   // Start the transaction.
1123   ASSERT_EQ(ERR_IO_PENDING,
1124             transaction_.Start(&request_info, callback_.callback(),
1125                                BoundNetLog()));
1126   ASSERT_EQ(OK, callback_.WaitForResult());
1127 
1128   // The transaction fires the callback when we can start reading data. That
1129   // means that the data socket should be open.
1130   MockTCPClientSocket* data_socket =
1131       static_cast<MockTCPClientSocket*>(transaction_.data_socket_.get());
1132   ASSERT_TRUE(data_socket);
1133   ASSERT_TRUE(data_socket->IsConnected());
1134 
1135   // Even if the PASV response specified some other address, we connect
1136   // to the address we used for control connection (which could be 127.0.0.1
1137   // or ::1 depending on whether we use IPv6).
1138   for (AddressList::const_iterator it = data_socket->addresses().begin();
1139       it != data_socket->addresses().end(); ++it) {
1140     EXPECT_NE("10.1.2.3", it->ToStringWithoutPort());
1141   }
1142 }
1143 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvReallyBadFormat1)1144 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) {
1145   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1146   if (GetFamily() == AF_INET)
1147     return;
1148 
1149   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n",
1150                                             FtpSocketDataProvider::PRE_QUIT);
1151   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1152 }
1153 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvReallyBadFormat2)1154 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) {
1155   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1156   if (GetFamily() == AF_INET)
1157     return;
1158 
1159   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n",
1160                                             FtpSocketDataProvider::PRE_QUIT);
1161   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1162 }
1163 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvReallyBadFormat3)1164 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) {
1165   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1166   if (GetFamily() == AF_INET)
1167     return;
1168 
1169   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n",
1170                                             FtpSocketDataProvider::PRE_QUIT);
1171   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1172 }
1173 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvReallyBadFormat4)1174 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) {
1175   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1176   if (GetFamily() == AF_INET)
1177     return;
1178 
1179   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n",
1180                                             FtpSocketDataProvider::PRE_QUIT);
1181   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1182 }
1183 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvReallyBadFormat5)1184 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) {
1185   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1186   if (GetFamily() == AF_INET)
1187     return;
1188 
1189   const char response[] = "227 Portscan (\0\0\031773\0)\r\n";
1190   FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
1191                                             FtpSocketDataProvider::PRE_QUIT);
1192   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1193 }
1194 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvUnsafePort1)1195 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
1196   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1197   if (GetFamily() == AF_INET)
1198     return;
1199 
1200   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
1201                                             FtpSocketDataProvider::PRE_QUIT);
1202   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1203 }
1204 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvUnsafePort2)1205 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
1206   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1207   if (GetFamily() == AF_INET)
1208     return;
1209 
1210   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
1211                                             FtpSocketDataProvider::PRE_QUIT);
1212   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1213 }
1214 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvUnsafePort3)1215 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
1216   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1217   if (GetFamily() == AF_INET)
1218     return;
1219 
1220   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
1221                                             FtpSocketDataProvider::PRE_QUIT);
1222   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1223 }
1224 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvUnsafePort4)1225 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
1226   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1227   if (GetFamily() == AF_INET)
1228     return;
1229 
1230   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
1231                                             FtpSocketDataProvider::PRE_QUIT);
1232   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1233 }
1234 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvWeirdSep)1235 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
1236   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1237   if (GetFamily() == AF_INET)
1238     return;
1239 
1240   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
1241                                             FtpSocketDataProvider::PRE_SIZE);
1242   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1243 }
1244 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvWeirdSepUnsafePort)1245 TEST_P(FtpNetworkTransactionTest,
1246        DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
1247   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1248   if (GetFamily() == AF_INET)
1249     return;
1250 
1251   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
1252                                             FtpSocketDataProvider::PRE_QUIT);
1253   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1254 }
1255 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilEpsvIllegalHost)1256 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
1257   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1258   if (GetFamily() == AF_INET)
1259     return;
1260 
1261   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1262                                             FtpSocketDataProvider::PRE_QUIT);
1263   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1264 }
1265 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadUsername)1266 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
1267   FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
1268   ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", 1, OK);
1269 }
1270 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadPassword)1271 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
1272   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
1273   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", 1, OK);
1274 }
1275 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionSpaceInLogin)1276 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
1277   FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
1278   ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", 1, OK);
1279 }
1280 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionSpaceInPassword)1281 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
1282   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
1283   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", 1, OK);
1284 }
1285 
TEST_P(FtpNetworkTransactionTest,EvilRestartUser)1286 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
1287   FtpSocketDataProvider ctrl_socket1;
1288   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1289                              FtpSocketDataProvider::PRE_QUIT,
1290                              "530 Login authentication failed\r\n");
1291   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1292 
1293   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1294 
1295   ASSERT_EQ(ERR_IO_PENDING,
1296             transaction_.Start(&request_info, callback_.callback(),
1297                                BoundNetLog()));
1298   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1299 
1300   MockRead ctrl_reads[] = {
1301     MockRead("220 host TestFTPd\r\n"),
1302     MockRead("221 Goodbye!\r\n"),
1303     MockRead(SYNCHRONOUS, OK),
1304   };
1305   MockWrite ctrl_writes[] = {
1306     MockWrite("QUIT\r\n"),
1307   };
1308   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1309                                         ctrl_writes, arraysize(ctrl_writes));
1310   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1311   ASSERT_EQ(ERR_IO_PENDING,
1312             transaction_.RestartWithAuth(
1313                 AuthCredentials(
1314                     base::ASCIIToUTF16("foo\nownz0red"),
1315                     base::ASCIIToUTF16("innocent")),
1316                 callback_.callback()));
1317   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1318 }
1319 
TEST_P(FtpNetworkTransactionTest,EvilRestartPassword)1320 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
1321   FtpSocketDataProvider ctrl_socket1;
1322   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1323                              FtpSocketDataProvider::PRE_QUIT,
1324                              "530 Login authentication failed\r\n");
1325   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1326 
1327   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1328 
1329   ASSERT_EQ(ERR_IO_PENDING,
1330             transaction_.Start(&request_info, callback_.callback(),
1331                                BoundNetLog()));
1332   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1333 
1334   MockRead ctrl_reads[] = {
1335     MockRead("220 host TestFTPd\r\n"),
1336     MockRead("331 User okay, send password\r\n"),
1337     MockRead("221 Goodbye!\r\n"),
1338     MockRead(SYNCHRONOUS, OK),
1339   };
1340   MockWrite ctrl_writes[] = {
1341     MockWrite("USER innocent\r\n"),
1342     MockWrite("QUIT\r\n"),
1343   };
1344   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1345                                         ctrl_writes, arraysize(ctrl_writes));
1346   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1347   ASSERT_EQ(ERR_IO_PENDING,
1348             transaction_.RestartWithAuth(
1349                 AuthCredentials(base::ASCIIToUTF16("innocent"),
1350                                 base::ASCIIToUTF16("foo\nownz0red")),
1351                 callback_.callback()));
1352   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1353 }
1354 
TEST_P(FtpNetworkTransactionTest,Escaping)1355 TEST_P(FtpNetworkTransactionTest, Escaping) {
1356   FtpSocketDataProviderEscaping ctrl_socket;
1357   ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
1358                      1, OK);
1359 }
1360 
1361 // Test for http://crbug.com/23794.
TEST_P(FtpNetworkTransactionTest,DownloadTransactionEvilSize)1362 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
1363   // Try to overflow int64 in the response.
1364   FtpSocketDataProviderEvilSize ctrl_socket(
1365       "213 99999999999999999999999999999999\r\n",
1366       FtpSocketDataProvider::PRE_QUIT);
1367   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1368 }
1369 
1370 // Test for http://crbug.com/36360.
TEST_P(FtpNetworkTransactionTest,DownloadTransactionBigSize)1371 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
1372   // Pass a valid, but large file size. The transaction should not fail.
1373   FtpSocketDataProviderEvilSize ctrl_socket(
1374       "213 3204427776\r\n",
1375       FtpSocketDataProvider::PRE_CWD);
1376   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1377   EXPECT_EQ(3204427776LL,
1378             transaction_.GetResponseInfo()->expected_content_size);
1379 }
1380 
1381 // Regression test for http://crbug.com/25023.
TEST_P(FtpNetworkTransactionTest,CloseConnection)1382 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
1383   FtpSocketDataProviderCloseConnection ctrl_socket;
1384   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, ERR_EMPTY_RESPONSE);
1385 }
1386 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailUser)1387 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
1388   FtpSocketDataProviderDirectoryListing ctrl_socket;
1389   // Use unallocated 599 FTP error code to make sure it falls into the generic
1390   // ERR_FTP_FAILED bucket.
1391   TransactionFailHelper(&ctrl_socket,
1392                         "ftp://host",
1393                         FtpSocketDataProvider::PRE_USER,
1394                         FtpSocketDataProvider::PRE_QUIT,
1395                         "599 fail\r\n",
1396                         ERR_FTP_FAILED);
1397 }
1398 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailPass)1399 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
1400   FtpSocketDataProviderDirectoryListing ctrl_socket;
1401   TransactionFailHelper(&ctrl_socket,
1402                         "ftp://host",
1403                         FtpSocketDataProvider::PRE_PASSWD,
1404                         FtpSocketDataProvider::PRE_QUIT,
1405                         "530 Login authentication failed\r\n",
1406                         ERR_FTP_FAILED);
1407 }
1408 
1409 // Regression test for http://crbug.com/38707.
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailPass503)1410 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
1411   FtpSocketDataProviderDirectoryListing ctrl_socket;
1412   TransactionFailHelper(&ctrl_socket,
1413                         "ftp://host",
1414                         FtpSocketDataProvider::PRE_PASSWD,
1415                         FtpSocketDataProvider::PRE_QUIT,
1416                         "503 Bad sequence of commands\r\n",
1417                         ERR_FTP_BAD_COMMAND_SEQUENCE);
1418 }
1419 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailSyst)1420 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
1421   FtpSocketDataProviderDirectoryListing ctrl_socket;
1422   // Use unallocated 599 FTP error code to make sure it falls into the generic
1423   // ERR_FTP_FAILED bucket.
1424   TransactionFailHelper(&ctrl_socket,
1425                         "ftp://host",
1426                         FtpSocketDataProvider::PRE_SYST,
1427                         FtpSocketDataProvider::PRE_PWD,
1428                         "599 fail\r\n",
1429                         OK);
1430 }
1431 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailPwd)1432 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
1433   FtpSocketDataProviderDirectoryListing ctrl_socket;
1434   // Use unallocated 599 FTP error code to make sure it falls into the generic
1435   // ERR_FTP_FAILED bucket.
1436   TransactionFailHelper(&ctrl_socket,
1437                         "ftp://host",
1438                         FtpSocketDataProvider::PRE_PWD,
1439                         FtpSocketDataProvider::PRE_QUIT,
1440                         "599 fail\r\n",
1441                         ERR_FTP_FAILED);
1442 }
1443 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailType)1444 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
1445   FtpSocketDataProviderDirectoryListing ctrl_socket;
1446   // Use unallocated 599 FTP error code to make sure it falls into the generic
1447   // ERR_FTP_FAILED bucket.
1448   TransactionFailHelper(&ctrl_socket,
1449                         "ftp://host",
1450                         FtpSocketDataProvider::PRE_TYPE,
1451                         FtpSocketDataProvider::PRE_QUIT,
1452                         "599 fail\r\n",
1453                         ERR_FTP_FAILED);
1454 }
1455 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailEpsv)1456 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
1457   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1458   if (GetFamily() == AF_INET)
1459     return;
1460 
1461   FtpSocketDataProviderDirectoryListing ctrl_socket;
1462   // Use unallocated 599 FTP error code to make sure it falls into the generic
1463   // ERR_FTP_FAILED bucket.
1464   TransactionFailHelper(&ctrl_socket,
1465                         "ftp://host",
1466                         FtpSocketDataProvider::PRE_EPSV,
1467                         FtpSocketDataProvider::PRE_NOPASV,
1468                         "599 fail\r\n",
1469                         ERR_FTP_FAILED);
1470 }
1471 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailCwd)1472 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1473   FtpSocketDataProviderDirectoryListing ctrl_socket;
1474   // Use unallocated 599 FTP error code to make sure it falls into the generic
1475   // ERR_FTP_FAILED bucket.
1476   TransactionFailHelper(&ctrl_socket,
1477                         "ftp://host",
1478                         FtpSocketDataProvider::PRE_CWD,
1479                         FtpSocketDataProvider::PRE_QUIT,
1480                         "599 fail\r\n",
1481                         ERR_FTP_FAILED);
1482 }
1483 
TEST_P(FtpNetworkTransactionTest,DirectoryTransactionFailList)1484 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1485   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1486   // Use unallocated 599 FTP error code to make sure it falls into the generic
1487   // ERR_FTP_FAILED bucket.
1488   TransactionFailHelper(&ctrl_socket,
1489                         "ftp://host/dir",
1490                         FtpSocketDataProvider::PRE_LIST,
1491                         FtpSocketDataProvider::PRE_QUIT,
1492                         "599 fail\r\n",
1493                         ERR_FTP_FAILED);
1494 }
1495 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailUser)1496 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1497   FtpSocketDataProviderFileDownload ctrl_socket;
1498   // Use unallocated 599 FTP error code to make sure it falls into the generic
1499   // ERR_FTP_FAILED bucket.
1500   TransactionFailHelper(&ctrl_socket,
1501                         "ftp://host/file",
1502                         FtpSocketDataProvider::PRE_USER,
1503                         FtpSocketDataProvider::PRE_QUIT,
1504                         "599 fail\r\n",
1505                         ERR_FTP_FAILED);
1506 }
1507 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailPass)1508 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1509   FtpSocketDataProviderFileDownload ctrl_socket;
1510   TransactionFailHelper(&ctrl_socket,
1511                         "ftp://host/file",
1512                         FtpSocketDataProvider::PRE_PASSWD,
1513                         FtpSocketDataProvider::PRE_QUIT,
1514                         "530 Login authentication failed\r\n",
1515                         ERR_FTP_FAILED);
1516 }
1517 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailSyst)1518 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1519   FtpSocketDataProviderFileDownload ctrl_socket;
1520   // Use unallocated 599 FTP error code to make sure it falls into the generic
1521   // ERR_FTP_FAILED bucket.
1522   TransactionFailHelper(&ctrl_socket,
1523                         "ftp://host/file",
1524                         FtpSocketDataProvider::PRE_SYST,
1525                         FtpSocketDataProvider::PRE_PWD,
1526                         "599 fail\r\n",
1527                         OK);
1528 }
1529 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailPwd)1530 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1531   FtpSocketDataProviderFileDownload ctrl_socket;
1532   // Use unallocated 599 FTP error code to make sure it falls into the generic
1533   // ERR_FTP_FAILED bucket.
1534   TransactionFailHelper(&ctrl_socket,
1535                         "ftp://host/file",
1536                         FtpSocketDataProvider::PRE_PWD,
1537                         FtpSocketDataProvider::PRE_QUIT,
1538                         "599 fail\r\n",
1539                         ERR_FTP_FAILED);
1540 }
1541 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailType)1542 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1543   FtpSocketDataProviderFileDownload ctrl_socket;
1544   // Use unallocated 599 FTP error code to make sure it falls into the generic
1545   // ERR_FTP_FAILED bucket.
1546   TransactionFailHelper(&ctrl_socket,
1547                         "ftp://host/file",
1548                         FtpSocketDataProvider::PRE_TYPE,
1549                         FtpSocketDataProvider::PRE_QUIT,
1550                         "599 fail\r\n",
1551                         ERR_FTP_FAILED);
1552 }
1553 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailEpsv)1554 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
1555   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1556   if (GetFamily() == AF_INET)
1557     return;
1558 
1559   FtpSocketDataProviderFileDownload ctrl_socket;
1560   // Use unallocated 599 FTP error code to make sure it falls into the generic
1561   // ERR_FTP_FAILED bucket.
1562   TransactionFailHelper(&ctrl_socket,
1563                         "ftp://host/file",
1564                         FtpSocketDataProvider::PRE_EPSV,
1565                         FtpSocketDataProvider::PRE_NOPASV,
1566                         "599 fail\r\n",
1567                         ERR_FTP_FAILED);
1568 }
1569 
TEST_P(FtpNetworkTransactionTest,DownloadTransactionFailRetr)1570 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1571   FtpSocketDataProviderFileDownload ctrl_socket;
1572   // Use unallocated 599 FTP error code to make sure it falls into the generic
1573   // ERR_FTP_FAILED bucket.
1574   TransactionFailHelper(&ctrl_socket,
1575                         "ftp://host/file",
1576                         FtpSocketDataProvider::PRE_RETR,
1577                         FtpSocketDataProvider::PRE_QUIT,
1578                         "599 fail\r\n",
1579                         ERR_FTP_FAILED);
1580 }
1581 
TEST_P(FtpNetworkTransactionTest,FileNotFound)1582 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
1583   FtpSocketDataProviderFileNotFound ctrl_socket;
1584   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 2, ERR_FTP_FAILED);
1585 }
1586 
1587 // Test for http://crbug.com/38845.
TEST_P(FtpNetworkTransactionTest,ZeroLengthDirInPWD)1588 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
1589   FtpSocketDataProviderFileDownload ctrl_socket;
1590   TransactionFailHelper(&ctrl_socket,
1591                         "ftp://host/file",
1592                         FtpSocketDataProvider::PRE_PWD,
1593                         FtpSocketDataProvider::PRE_TYPE,
1594                         "257 \"\"\r\n",
1595                         OK);
1596 }
1597 
1598 INSTANTIATE_TEST_CASE_P(FTP,
1599                         FtpNetworkTransactionTest,
1600                         ::testing::Values(AF_INET, AF_INET6));
1601 
1602 }  // namespace net
1603