Home | History | Annotate | Download | only in ftp
      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 (at) 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   const char response[] = "227 Portscan (\0\0\031773\0)\r\n";
   1190   FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
   1191                                             FtpSocketDataProvider::PRE_QUIT);
   1192   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
   1193 }
   1194 
   1195 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
   1196   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1197   if (GetFamily() == AF_INET)
   1198     return;
   1199 
   1200   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
   1201                                             FtpSocketDataProvider::PRE_QUIT);
   1202   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
   1203 }
   1204 
   1205 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
   1206   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1207   if (GetFamily() == AF_INET)
   1208     return;
   1209 
   1210   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
   1211                                             FtpSocketDataProvider::PRE_QUIT);
   1212   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
   1213 }
   1214 
   1215 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
   1216   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1217   if (GetFamily() == AF_INET)
   1218     return;
   1219 
   1220   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
   1221                                             FtpSocketDataProvider::PRE_QUIT);
   1222   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
   1223 }
   1224 
   1225 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
   1226   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1227   if (GetFamily() == AF_INET)
   1228     return;
   1229 
   1230   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
   1231                                             FtpSocketDataProvider::PRE_QUIT);
   1232   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
   1233 }
   1234 
   1235 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
   1236   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1237   if (GetFamily() == AF_INET)
   1238     return;
   1239 
   1240   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
   1241                                             FtpSocketDataProvider::PRE_SIZE);
   1242   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
   1243 }
   1244 
   1245 TEST_P(FtpNetworkTransactionTest,
   1246        DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
   1247   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1248   if (GetFamily() == AF_INET)
   1249     return;
   1250 
   1251   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
   1252                                             FtpSocketDataProvider::PRE_QUIT);
   1253   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_UNSAFE_PORT);
   1254 }
   1255 
   1256 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
   1257   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1258   if (GetFamily() == AF_INET)
   1259     return;
   1260 
   1261   FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
   1262                                             FtpSocketDataProvider::PRE_QUIT);
   1263   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
   1264 }
   1265 
   1266 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
   1267   FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
   1268   ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", 1, OK);
   1269 }
   1270 
   1271 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
   1272   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
   1273   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", 1, OK);
   1274 }
   1275 
   1276 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
   1277   FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
   1278   ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", 1, OK);
   1279 }
   1280 
   1281 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
   1282   FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
   1283   ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", 1, OK);
   1284 }
   1285 
   1286 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
   1287   FtpSocketDataProvider ctrl_socket1;
   1288   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
   1289                              FtpSocketDataProvider::PRE_QUIT,
   1290                              "530 Login authentication failed\r\n");
   1291   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
   1292 
   1293   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
   1294 
   1295   ASSERT_EQ(ERR_IO_PENDING,
   1296             transaction_.Start(&request_info, callback_.callback(),
   1297                                BoundNetLog()));
   1298   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
   1299 
   1300   MockRead ctrl_reads[] = {
   1301     MockRead("220 host TestFTPd\r\n"),
   1302     MockRead("221 Goodbye!\r\n"),
   1303     MockRead(SYNCHRONOUS, OK),
   1304   };
   1305   MockWrite ctrl_writes[] = {
   1306     MockWrite("QUIT\r\n"),
   1307   };
   1308   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
   1309                                         ctrl_writes, arraysize(ctrl_writes));
   1310   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
   1311   ASSERT_EQ(ERR_IO_PENDING,
   1312             transaction_.RestartWithAuth(
   1313                 AuthCredentials(
   1314                     base::ASCIIToUTF16("foo\nownz0red"),
   1315                     base::ASCIIToUTF16("innocent")),
   1316                 callback_.callback()));
   1317   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
   1318 }
   1319 
   1320 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
   1321   FtpSocketDataProvider ctrl_socket1;
   1322   ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
   1323                              FtpSocketDataProvider::PRE_QUIT,
   1324                              "530 Login authentication failed\r\n");
   1325   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
   1326 
   1327   FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
   1328 
   1329   ASSERT_EQ(ERR_IO_PENDING,
   1330             transaction_.Start(&request_info, callback_.callback(),
   1331                                BoundNetLog()));
   1332   ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
   1333 
   1334   MockRead ctrl_reads[] = {
   1335     MockRead("220 host TestFTPd\r\n"),
   1336     MockRead("331 User okay, send password\r\n"),
   1337     MockRead("221 Goodbye!\r\n"),
   1338     MockRead(SYNCHRONOUS, OK),
   1339   };
   1340   MockWrite ctrl_writes[] = {
   1341     MockWrite("USER innocent\r\n"),
   1342     MockWrite("QUIT\r\n"),
   1343   };
   1344   StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
   1345                                         ctrl_writes, arraysize(ctrl_writes));
   1346   mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
   1347   ASSERT_EQ(ERR_IO_PENDING,
   1348             transaction_.RestartWithAuth(
   1349                 AuthCredentials(base::ASCIIToUTF16("innocent"),
   1350                                 base::ASCIIToUTF16("foo\nownz0red")),
   1351                 callback_.callback()));
   1352   EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
   1353 }
   1354 
   1355 TEST_P(FtpNetworkTransactionTest, Escaping) {
   1356   FtpSocketDataProviderEscaping ctrl_socket;
   1357   ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
   1358                      1, OK);
   1359 }
   1360 
   1361 // Test for http://crbug.com/23794.
   1362 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
   1363   // Try to overflow int64 in the response.
   1364   FtpSocketDataProviderEvilSize ctrl_socket(
   1365       "213 99999999999999999999999999999999\r\n",
   1366       FtpSocketDataProvider::PRE_QUIT);
   1367   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, ERR_INVALID_RESPONSE);
   1368 }
   1369 
   1370 // Test for http://crbug.com/36360.
   1371 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
   1372   // Pass a valid, but large file size. The transaction should not fail.
   1373   FtpSocketDataProviderEvilSize ctrl_socket(
   1374       "213 3204427776\r\n",
   1375       FtpSocketDataProvider::PRE_CWD);
   1376   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 1, OK);
   1377   EXPECT_EQ(3204427776LL,
   1378             transaction_.GetResponseInfo()->expected_content_size);
   1379 }
   1380 
   1381 // Regression test for http://crbug.com/25023.
   1382 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
   1383   FtpSocketDataProviderCloseConnection ctrl_socket;
   1384   ExecuteTransaction(&ctrl_socket, "ftp://host", 1, ERR_EMPTY_RESPONSE);
   1385 }
   1386 
   1387 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
   1388   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1389   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1390   // ERR_FTP_FAILED bucket.
   1391   TransactionFailHelper(&ctrl_socket,
   1392                         "ftp://host",
   1393                         FtpSocketDataProvider::PRE_USER,
   1394                         FtpSocketDataProvider::PRE_QUIT,
   1395                         "599 fail\r\n",
   1396                         ERR_FTP_FAILED);
   1397 }
   1398 
   1399 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
   1400   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1401   TransactionFailHelper(&ctrl_socket,
   1402                         "ftp://host",
   1403                         FtpSocketDataProvider::PRE_PASSWD,
   1404                         FtpSocketDataProvider::PRE_QUIT,
   1405                         "530 Login authentication failed\r\n",
   1406                         ERR_FTP_FAILED);
   1407 }
   1408 
   1409 // Regression test for http://crbug.com/38707.
   1410 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
   1411   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1412   TransactionFailHelper(&ctrl_socket,
   1413                         "ftp://host",
   1414                         FtpSocketDataProvider::PRE_PASSWD,
   1415                         FtpSocketDataProvider::PRE_QUIT,
   1416                         "503 Bad sequence of commands\r\n",
   1417                         ERR_FTP_BAD_COMMAND_SEQUENCE);
   1418 }
   1419 
   1420 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
   1421   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1422   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1423   // ERR_FTP_FAILED bucket.
   1424   TransactionFailHelper(&ctrl_socket,
   1425                         "ftp://host",
   1426                         FtpSocketDataProvider::PRE_SYST,
   1427                         FtpSocketDataProvider::PRE_PWD,
   1428                         "599 fail\r\n",
   1429                         OK);
   1430 }
   1431 
   1432 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
   1433   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1434   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1435   // ERR_FTP_FAILED bucket.
   1436   TransactionFailHelper(&ctrl_socket,
   1437                         "ftp://host",
   1438                         FtpSocketDataProvider::PRE_PWD,
   1439                         FtpSocketDataProvider::PRE_QUIT,
   1440                         "599 fail\r\n",
   1441                         ERR_FTP_FAILED);
   1442 }
   1443 
   1444 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
   1445   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1446   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1447   // ERR_FTP_FAILED bucket.
   1448   TransactionFailHelper(&ctrl_socket,
   1449                         "ftp://host",
   1450                         FtpSocketDataProvider::PRE_TYPE,
   1451                         FtpSocketDataProvider::PRE_QUIT,
   1452                         "599 fail\r\n",
   1453                         ERR_FTP_FAILED);
   1454 }
   1455 
   1456 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
   1457   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1458   if (GetFamily() == AF_INET)
   1459     return;
   1460 
   1461   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1462   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1463   // ERR_FTP_FAILED bucket.
   1464   TransactionFailHelper(&ctrl_socket,
   1465                         "ftp://host",
   1466                         FtpSocketDataProvider::PRE_EPSV,
   1467                         FtpSocketDataProvider::PRE_NOPASV,
   1468                         "599 fail\r\n",
   1469                         ERR_FTP_FAILED);
   1470 }
   1471 
   1472 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
   1473   FtpSocketDataProviderDirectoryListing ctrl_socket;
   1474   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1475   // ERR_FTP_FAILED bucket.
   1476   TransactionFailHelper(&ctrl_socket,
   1477                         "ftp://host",
   1478                         FtpSocketDataProvider::PRE_CWD,
   1479                         FtpSocketDataProvider::PRE_QUIT,
   1480                         "599 fail\r\n",
   1481                         ERR_FTP_FAILED);
   1482 }
   1483 
   1484 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
   1485   FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
   1486   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1487   // ERR_FTP_FAILED bucket.
   1488   TransactionFailHelper(&ctrl_socket,
   1489                         "ftp://host/dir",
   1490                         FtpSocketDataProvider::PRE_LIST,
   1491                         FtpSocketDataProvider::PRE_QUIT,
   1492                         "599 fail\r\n",
   1493                         ERR_FTP_FAILED);
   1494 }
   1495 
   1496 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
   1497   FtpSocketDataProviderFileDownload ctrl_socket;
   1498   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1499   // ERR_FTP_FAILED bucket.
   1500   TransactionFailHelper(&ctrl_socket,
   1501                         "ftp://host/file",
   1502                         FtpSocketDataProvider::PRE_USER,
   1503                         FtpSocketDataProvider::PRE_QUIT,
   1504                         "599 fail\r\n",
   1505                         ERR_FTP_FAILED);
   1506 }
   1507 
   1508 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
   1509   FtpSocketDataProviderFileDownload ctrl_socket;
   1510   TransactionFailHelper(&ctrl_socket,
   1511                         "ftp://host/file",
   1512                         FtpSocketDataProvider::PRE_PASSWD,
   1513                         FtpSocketDataProvider::PRE_QUIT,
   1514                         "530 Login authentication failed\r\n",
   1515                         ERR_FTP_FAILED);
   1516 }
   1517 
   1518 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
   1519   FtpSocketDataProviderFileDownload ctrl_socket;
   1520   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1521   // ERR_FTP_FAILED bucket.
   1522   TransactionFailHelper(&ctrl_socket,
   1523                         "ftp://host/file",
   1524                         FtpSocketDataProvider::PRE_SYST,
   1525                         FtpSocketDataProvider::PRE_PWD,
   1526                         "599 fail\r\n",
   1527                         OK);
   1528 }
   1529 
   1530 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
   1531   FtpSocketDataProviderFileDownload ctrl_socket;
   1532   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1533   // ERR_FTP_FAILED bucket.
   1534   TransactionFailHelper(&ctrl_socket,
   1535                         "ftp://host/file",
   1536                         FtpSocketDataProvider::PRE_PWD,
   1537                         FtpSocketDataProvider::PRE_QUIT,
   1538                         "599 fail\r\n",
   1539                         ERR_FTP_FAILED);
   1540 }
   1541 
   1542 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
   1543   FtpSocketDataProviderFileDownload ctrl_socket;
   1544   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1545   // ERR_FTP_FAILED bucket.
   1546   TransactionFailHelper(&ctrl_socket,
   1547                         "ftp://host/file",
   1548                         FtpSocketDataProvider::PRE_TYPE,
   1549                         FtpSocketDataProvider::PRE_QUIT,
   1550                         "599 fail\r\n",
   1551                         ERR_FTP_FAILED);
   1552 }
   1553 
   1554 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
   1555   // This test makes no sense for IPv4 connections (we don't use EPSV there).
   1556   if (GetFamily() == AF_INET)
   1557     return;
   1558 
   1559   FtpSocketDataProviderFileDownload ctrl_socket;
   1560   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1561   // ERR_FTP_FAILED bucket.
   1562   TransactionFailHelper(&ctrl_socket,
   1563                         "ftp://host/file",
   1564                         FtpSocketDataProvider::PRE_EPSV,
   1565                         FtpSocketDataProvider::PRE_NOPASV,
   1566                         "599 fail\r\n",
   1567                         ERR_FTP_FAILED);
   1568 }
   1569 
   1570 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
   1571   FtpSocketDataProviderFileDownload ctrl_socket;
   1572   // Use unallocated 599 FTP error code to make sure it falls into the generic
   1573   // ERR_FTP_FAILED bucket.
   1574   TransactionFailHelper(&ctrl_socket,
   1575                         "ftp://host/file",
   1576                         FtpSocketDataProvider::PRE_RETR,
   1577                         FtpSocketDataProvider::PRE_QUIT,
   1578                         "599 fail\r\n",
   1579                         ERR_FTP_FAILED);
   1580 }
   1581 
   1582 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
   1583   FtpSocketDataProviderFileNotFound ctrl_socket;
   1584   ExecuteTransaction(&ctrl_socket, "ftp://host/file", 2, ERR_FTP_FAILED);
   1585 }
   1586 
   1587 // Test for http://crbug.com/38845.
   1588 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
   1589   FtpSocketDataProviderFileDownload ctrl_socket;
   1590   TransactionFailHelper(&ctrl_socket,
   1591                         "ftp://host/file",
   1592                         FtpSocketDataProvider::PRE_PWD,
   1593                         FtpSocketDataProvider::PRE_TYPE,
   1594                         "257 \"\"\r\n",
   1595                         OK);
   1596 }
   1597 
   1598 INSTANTIATE_TEST_CASE_P(FTP,
   1599                         FtpNetworkTransactionTest,
   1600                         ::testing::Values(AF_INET, AF_INET6));
   1601 
   1602 }  // namespace net
   1603