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