Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / net / ftp / ftp_network_transaction_unittest.cc
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
58   FtpSocketDataProvider()
59       : failure_injection_state_(NONE),
60         multiline_welcome_(false),
61         use_epsv_(true),
62         data_type_('I') {
63     Init();
64   }
65
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
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
130   State state() const {
131     return state_;
132   }
133
134   virtual void Reset() OVERRIDE {
135     DynamicSocketDataProvider::Reset();
136     Init();
137   }
138
139   void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; }
140
141   bool use_epsv() const { return use_epsv_; }
142   void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; }
143
144   void set_data_type(char data_type) { data_type_ = data_type; }
145
146  protected:
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.
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
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
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:
205   FtpSocketDataProviderDirectoryListing() {
206   }
207
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:
232   FtpSocketDataProviderDirectoryListingWithPasvFallback() {
233   }
234
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:
258   FtpSocketDataProviderDirectoryListingZeroSize() {
259   }
260
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:
278   FtpSocketDataProviderVMSDirectoryListing() {
279   }
280
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:
312   FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
313   }
314
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:
348   FtpSocketDataProviderFileDownloadWithFileTypecode() {
349   }
350
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:
371   FtpSocketDataProviderFileDownload() {
372   }
373
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:
398   FtpSocketDataProviderFileNotFound() {
399   }
400
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:
428   FtpSocketDataProviderFileDownloadWithPasvFallback() {
429   }
430
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:
453   FtpSocketDataProviderFileDownloadZeroSize() {
454   }
455
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:
479   FtpSocketDataProviderFileDownloadCWD451() {
480   }
481
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:
501   FtpSocketDataProviderVMSFileDownload() {
502   }
503
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:
536   FtpSocketDataProviderEscaping() {
537   }
538
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:
565   FtpSocketDataProviderFileDownloadTransferStarting() {
566   }
567
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:
589   FtpSocketDataProviderDirectoryListingTransferStarting() {
590   }
591
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:
614   FtpSocketDataProviderFileDownloadInvalidResponse() {
615   }
616
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:
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
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
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:
674   FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state)
675       : pasv_response_(pasv_response),
676         expected_state_(expected_state) {
677   }
678
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:
699   FtpSocketDataProviderEvilSize(const char* size_response, State expected_state)
700       : size_response_(size_response),
701         expected_state_(expected_state) {
702   }
703
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:
725   FtpSocketDataProviderEvilLogin(const char* expected_user,
726                                 const char* expected_password)
727       : expected_user_(expected_user),
728         expected_password_(expected_password) {
729   }
730
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:
755   FtpSocketDataProviderCloseConnection() {
756   }
757
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:
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).
797   int GetFamily() {
798     return GetParam();
799   }
800
801   FtpRequestInfo GetRequestInfo(const std::string& url) {
802     FtpRequestInfo info;
803     info.url = GURL(url);
804     return info;
805   }
806
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
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
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.
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
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
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
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
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
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
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
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.
974 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
975   FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
976   ExecuteTransaction(&ctrl_socket, "ftp://host", 0, OK);
977 }
978
979 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
980   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
981   ExecuteTransaction(&ctrl_socket, "ftp://host/dir", 1, OK);
982 }
983
984 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
985   FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
986   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
987 }
988
989 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
990   FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
991   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, OK);
992 }
993
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
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
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
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
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
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
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
1048 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
1049   FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
1050   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1051 }
1052
1053 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) {
1054   FtpSocketDataProviderFileDownloadCWD451 ctrl_socket;
1055   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1056 }
1057
1058 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) {
1059   FtpSocketDataProviderVMSFileDownload ctrl_socket;
1060   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1061 }
1062
1063 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
1064   FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
1065   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1066 }
1067
1068 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
1069   FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
1070   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1071 }
1072
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
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
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
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
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
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
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
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
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
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
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   // Breaking the string in the next line prevents MSVC warning C4125.
1190   const char response[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1191   FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
1192                                             FtpSocketDataProvider::PRE_QUIT);
1193   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1194 }
1195
1196 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
1197   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1198   if (GetFamily() == AF_INET)
1199     return;
1200
1201   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
1202                                             FtpSocketDataProvider::PRE_QUIT);
1203   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1204 }
1205
1206 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
1207   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1208   if (GetFamily() == AF_INET)
1209     return;
1210
1211   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
1212                                             FtpSocketDataProvider::PRE_QUIT);
1213   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1214 }
1215
1216 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
1217   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1218   if (GetFamily() == AF_INET)
1219     return;
1220
1221   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
1222                                             FtpSocketDataProvider::PRE_QUIT);
1223   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1224 }
1225
1226 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
1227   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1228   if (GetFamily() == AF_INET)
1229     return;
1230
1231   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
1232                                             FtpSocketDataProvider::PRE_QUIT);
1233   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1234 }
1235
1236 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
1237   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1238   if (GetFamily() == AF_INET)
1239     return;
1240
1241   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
1242                                             FtpSocketDataProvider::PRE_SIZE);
1243   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1244 }
1245
1246 TEST_P(FtpNetworkTransactionTest,
1247        DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
1248   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1249   if (GetFamily() == AF_INET)
1250     return;
1251
1252   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
1253                                             FtpSocketDataProvider::PRE_QUIT);
1254   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
1255 }
1256
1257 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
1258   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1259   if (GetFamily() == AF_INET)
1260     return;
1261
1262   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1263                                             FtpSocketDataProvider::PRE_QUIT);
1264   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1265 }
1266
1267 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
1268   FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
1269   ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", 1, OK);
1270 }
1271
1272 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
1273   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
1274   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", 1, OK);
1275 }
1276
1277 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
1278   FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
1279   ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", 1, OK);
1280 }
1281
1282 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
1283   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
1284   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", 1, OK);
1285 }
1286
1287 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
1288   FtpSocketDataProvider ctrl_socket1;
1289   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1290                              FtpSocketDataProvider::PRE_QUIT,
1291                              "530 Login authentication failed\r\n");
1292   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1293
1294   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1295
1296   ASSERT_EQ(ERR_IO_PENDING,
1297             transaction_.Start(&request_info, callback_.callback(),
1298                                BoundNetLog()));
1299   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1300
1301   MockRead ctrl_reads[] = {
1302     MockRead("220 host TestFTPd\r\n"),
1303     MockRead("221 Goodbye!\r\n"),
1304     MockRead(SYNCHRONOUS, OK),
1305   };
1306   MockWrite ctrl_writes[] = {
1307     MockWrite("QUIT\r\n"),
1308   };
1309   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1310                                         ctrl_writes, arraysize(ctrl_writes));
1311   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1312   ASSERT_EQ(ERR_IO_PENDING,
1313             transaction_.RestartWithAuth(
1314                 AuthCredentials(
1315                     base::ASCIIToUTF16("foo\nownz0red"),
1316                     base::ASCIIToUTF16("innocent")),
1317                 callback_.callback()));
1318   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1319 }
1320
1321 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
1322   FtpSocketDataProvider ctrl_socket1;
1323   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1324                              FtpSocketDataProvider::PRE_QUIT,
1325                              "530 Login authentication failed\r\n");
1326   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1327
1328   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1329
1330   ASSERT_EQ(ERR_IO_PENDING,
1331             transaction_.Start(&request_info, callback_.callback(),
1332                                BoundNetLog()));
1333   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1334
1335   MockRead ctrl_reads[] = {
1336     MockRead("220 host TestFTPd\r\n"),
1337     MockRead("331 User okay, send password\r\n"),
1338     MockRead("221 Goodbye!\r\n"),
1339     MockRead(SYNCHRONOUS, OK),
1340   };
1341   MockWrite ctrl_writes[] = {
1342     MockWrite("USER innocent\r\n"),
1343     MockWrite("QUIT\r\n"),
1344   };
1345   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1346                                         ctrl_writes, arraysize(ctrl_writes));
1347   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1348   ASSERT_EQ(ERR_IO_PENDING,
1349             transaction_.RestartWithAuth(
1350                 AuthCredentials(base::ASCIIToUTF16("innocent"),
1351                                 base::ASCIIToUTF16("foo\nownz0red")),
1352                 callback_.callback()));
1353   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1354 }
1355
1356 TEST_P(FtpNetworkTransactionTest, Escaping) {
1357   FtpSocketDataProviderEscaping ctrl_socket;
1358   ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
1359                      1, OK);
1360 }
1361
1362 // Test for http://crbug.com/23794.
1363 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
1364   // Try to overflow int64 in the response.
1365   FtpSocketDataProviderEvilSize ctrl_socket(
1366       "213 99999999999999999999999999999999\r\n",
1367       FtpSocketDataProvider::PRE_QUIT);
1368   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
1369 }
1370
1371 // Test for http://crbug.com/36360.
1372 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
1373   // Pass a valid, but large file size. The transaction should not fail.
1374   FtpSocketDataProviderEvilSize ctrl_socket(
1375       "213 3204427776\r\n",
1376       FtpSocketDataProvider::PRE_CWD);
1377   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
1378   EXPECT_EQ(3204427776LL,
1379             transaction_.GetResponseInfo()->expected_content_size);
1380 }
1381
1382 // Regression test for http://crbug.com/25023.
1383 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
1384   FtpSocketDataProviderCloseConnection ctrl_socket;
1385   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, ERR_EMPTY_RESPONSE);
1386 }
1387
1388 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
1389   FtpSocketDataProviderDirectoryListing ctrl_socket;
1390   // Use unallocated 599 FTP error code to make sure it falls into the generic
1391   // ERR_FTP_FAILED bucket.
1392   TransactionFailHelper(&ctrl_socket,
1393                         "ftp://host",
1394                         FtpSocketDataProvider::PRE_USER,
1395                         FtpSocketDataProvider::PRE_QUIT,
1396                         "599 fail\r\n",
1397                         ERR_FTP_FAILED);
1398 }
1399
1400 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
1401   FtpSocketDataProviderDirectoryListing ctrl_socket;
1402   TransactionFailHelper(&ctrl_socket,
1403                         "ftp://host",
1404                         FtpSocketDataProvider::PRE_PASSWD,
1405                         FtpSocketDataProvider::PRE_QUIT,
1406                         "530 Login authentication failed\r\n",
1407                         ERR_FTP_FAILED);
1408 }
1409
1410 // Regression test for http://crbug.com/38707.
1411 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
1412   FtpSocketDataProviderDirectoryListing ctrl_socket;
1413   TransactionFailHelper(&ctrl_socket,
1414                         "ftp://host",
1415                         FtpSocketDataProvider::PRE_PASSWD,
1416                         FtpSocketDataProvider::PRE_QUIT,
1417                         "503 Bad sequence of commands\r\n",
1418                         ERR_FTP_BAD_COMMAND_SEQUENCE);
1419 }
1420
1421 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
1422   FtpSocketDataProviderDirectoryListing ctrl_socket;
1423   // Use unallocated 599 FTP error code to make sure it falls into the generic
1424   // ERR_FTP_FAILED bucket.
1425   TransactionFailHelper(&ctrl_socket,
1426                         "ftp://host",
1427                         FtpSocketDataProvider::PRE_SYST,
1428                         FtpSocketDataProvider::PRE_PWD,
1429                         "599 fail\r\n",
1430                         OK);
1431 }
1432
1433 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
1434   FtpSocketDataProviderDirectoryListing ctrl_socket;
1435   // Use unallocated 599 FTP error code to make sure it falls into the generic
1436   // ERR_FTP_FAILED bucket.
1437   TransactionFailHelper(&ctrl_socket,
1438                         "ftp://host",
1439                         FtpSocketDataProvider::PRE_PWD,
1440                         FtpSocketDataProvider::PRE_QUIT,
1441                         "599 fail\r\n",
1442                         ERR_FTP_FAILED);
1443 }
1444
1445 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
1446   FtpSocketDataProviderDirectoryListing ctrl_socket;
1447   // Use unallocated 599 FTP error code to make sure it falls into the generic
1448   // ERR_FTP_FAILED bucket.
1449   TransactionFailHelper(&ctrl_socket,
1450                         "ftp://host",
1451                         FtpSocketDataProvider::PRE_TYPE,
1452                         FtpSocketDataProvider::PRE_QUIT,
1453                         "599 fail\r\n",
1454                         ERR_FTP_FAILED);
1455 }
1456
1457 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
1458   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1459   if (GetFamily() == AF_INET)
1460     return;
1461
1462   FtpSocketDataProviderDirectoryListing ctrl_socket;
1463   // Use unallocated 599 FTP error code to make sure it falls into the generic
1464   // ERR_FTP_FAILED bucket.
1465   TransactionFailHelper(&ctrl_socket,
1466                         "ftp://host",
1467                         FtpSocketDataProvider::PRE_EPSV,
1468                         FtpSocketDataProvider::PRE_NOPASV,
1469                         "599 fail\r\n",
1470                         ERR_FTP_FAILED);
1471 }
1472
1473 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1474   FtpSocketDataProviderDirectoryListing ctrl_socket;
1475   // Use unallocated 599 FTP error code to make sure it falls into the generic
1476   // ERR_FTP_FAILED bucket.
1477   TransactionFailHelper(&ctrl_socket,
1478                         "ftp://host",
1479                         FtpSocketDataProvider::PRE_CWD,
1480                         FtpSocketDataProvider::PRE_QUIT,
1481                         "599 fail\r\n",
1482                         ERR_FTP_FAILED);
1483 }
1484
1485 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1486   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1487   // Use unallocated 599 FTP error code to make sure it falls into the generic
1488   // ERR_FTP_FAILED bucket.
1489   TransactionFailHelper(&ctrl_socket,
1490                         "ftp://host/dir",
1491                         FtpSocketDataProvider::PRE_LIST,
1492                         FtpSocketDataProvider::PRE_QUIT,
1493                         "599 fail\r\n",
1494                         ERR_FTP_FAILED);
1495 }
1496
1497 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1498   FtpSocketDataProviderFileDownload ctrl_socket;
1499   // Use unallocated 599 FTP error code to make sure it falls into the generic
1500   // ERR_FTP_FAILED bucket.
1501   TransactionFailHelper(&ctrl_socket,
1502                         "ftp://host/file",
1503                         FtpSocketDataProvider::PRE_USER,
1504                         FtpSocketDataProvider::PRE_QUIT,
1505                         "599 fail\r\n",
1506                         ERR_FTP_FAILED);
1507 }
1508
1509 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1510   FtpSocketDataProviderFileDownload ctrl_socket;
1511   TransactionFailHelper(&ctrl_socket,
1512                         "ftp://host/file",
1513                         FtpSocketDataProvider::PRE_PASSWD,
1514                         FtpSocketDataProvider::PRE_QUIT,
1515                         "530 Login authentication failed\r\n",
1516                         ERR_FTP_FAILED);
1517 }
1518
1519 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1520   FtpSocketDataProviderFileDownload ctrl_socket;
1521   // Use unallocated 599 FTP error code to make sure it falls into the generic
1522   // ERR_FTP_FAILED bucket.
1523   TransactionFailHelper(&ctrl_socket,
1524                         "ftp://host/file",
1525                         FtpSocketDataProvider::PRE_SYST,
1526                         FtpSocketDataProvider::PRE_PWD,
1527                         "599 fail\r\n",
1528                         OK);
1529 }
1530
1531 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1532   FtpSocketDataProviderFileDownload ctrl_socket;
1533   // Use unallocated 599 FTP error code to make sure it falls into the generic
1534   // ERR_FTP_FAILED bucket.
1535   TransactionFailHelper(&ctrl_socket,
1536                         "ftp://host/file",
1537                         FtpSocketDataProvider::PRE_PWD,
1538                         FtpSocketDataProvider::PRE_QUIT,
1539                         "599 fail\r\n",
1540                         ERR_FTP_FAILED);
1541 }
1542
1543 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1544   FtpSocketDataProviderFileDownload ctrl_socket;
1545   // Use unallocated 599 FTP error code to make sure it falls into the generic
1546   // ERR_FTP_FAILED bucket.
1547   TransactionFailHelper(&ctrl_socket,
1548                         "ftp://host/file",
1549                         FtpSocketDataProvider::PRE_TYPE,
1550                         FtpSocketDataProvider::PRE_QUIT,
1551                         "599 fail\r\n",
1552                         ERR_FTP_FAILED);
1553 }
1554
1555 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
1556   // This test makes no sense for IPv4 connections (we don't use EPSV there).
1557   if (GetFamily() == AF_INET)
1558     return;
1559
1560   FtpSocketDataProviderFileDownload ctrl_socket;
1561   // Use unallocated 599 FTP error code to make sure it falls into the generic
1562   // ERR_FTP_FAILED bucket.
1563   TransactionFailHelper(&ctrl_socket,
1564                         "ftp://host/file",
1565                         FtpSocketDataProvider::PRE_EPSV,
1566                         FtpSocketDataProvider::PRE_NOPASV,
1567                         "599 fail\r\n",
1568                         ERR_FTP_FAILED);
1569 }
1570
1571 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1572   FtpSocketDataProviderFileDownload ctrl_socket;
1573   // Use unallocated 599 FTP error code to make sure it falls into the generic
1574   // ERR_FTP_FAILED bucket.
1575   TransactionFailHelper(&ctrl_socket,
1576                         "ftp://host/file",
1577                         FtpSocketDataProvider::PRE_RETR,
1578                         FtpSocketDataProvider::PRE_QUIT,
1579                         "599 fail\r\n",
1580                         ERR_FTP_FAILED);
1581 }
1582
1583 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
1584   FtpSocketDataProviderFileNotFound ctrl_socket;
1585   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 2, ERR_FTP_FAILED);
1586 }
1587
1588 // Test for http://crbug.com/38845.
1589 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
1590   FtpSocketDataProviderFileDownload ctrl_socket;
1591   TransactionFailHelper(&ctrl_socket,
1592                         "ftp://host/file",
1593                         FtpSocketDataProvider::PRE_PWD,
1594                         FtpSocketDataProvider::PRE_TYPE,
1595                         "257 \"\"\r\n",
1596                         OK);
1597 }
1598
1599 INSTANTIATE_TEST_CASE_P(FTP,
1600                         FtpNetworkTransactionTest,
1601                         ::testing::Values(AF_INET, AF_INET6));
1602
1603 }  // namespace net