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