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