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.
5 #include "net/ftp/ftp_network_transaction.h"
7 #include "build/build_config.h"
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"
27 // Size we use for IOBuffers used to receive data from the test data socket.
28 const int kBufferSize
= 128;
34 class FtpSocketDataProvider
: public DynamicSocketDataProvider
{
56 FtpSocketDataProvider()
57 : failure_injection_state_(NONE
),
58 multiline_welcome_(false),
64 MockWriteResult
OnWrite(const std::string
& data
) override
{
66 return MockWriteResult(ASYNC
, data
.length());
69 return Verify("USER anonymous\r\n", data
, PRE_PASSWD
,
70 "331 Password needed\r\n");
73 static const char response_one
[] = "230 Welcome\r\n";
74 static const char response_multi
[] =
75 "230- One\r\n230- Two\r\n230 Three\r\n";
76 return Verify("PASS chrome@example.com\r\n", data
, PRE_SYST
,
77 multiline_welcome_
? response_multi
: response_one
);
80 return Verify("SYST\r\n", data
, PRE_PWD
, "215 UNIX\r\n");
82 return Verify("PWD\r\n", data
, PRE_TYPE
,
83 "257 \"/\" is your current location\r\n");
85 return Verify(std::string("TYPE ") + data_type_
+ "\r\n", data
,
86 PRE_SIZE
, "200 TYPE set successfully\r\n");
88 return Verify("EPSV\r\n", data
, PRE_LIST
,
89 "227 Entering Extended Passive Mode (|||31744|)\r\n");
91 return Verify("PASV\r\n", data
, PRE_LIST
,
92 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
94 return Verify("EPSV\r\n", data
, PRE_RETR
,
95 "227 Entering Extended Passive Mode (|||31744|)\r\n");
97 return Verify("PASV\r\n", data
, PRE_RETR
,
98 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
100 // Use unallocated 599 FTP error code to make sure it falls into the
101 // generic ERR_FTP_FAILED bucket.
102 return Verify("PASV\r\n", data
, PRE_QUIT
,
105 return Verify("QUIT\r\n", data
, QUIT
, "221 Goodbye.\r\n");
107 NOTREACHED() << "State not handled " << state();
108 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
112 void InjectFailure(State state
, State next_state
, const char* response
) {
113 DCHECK_EQ(NONE
, failure_injection_state_
);
114 DCHECK_NE(NONE
, state
);
115 DCHECK_NE(NONE
, next_state
);
116 DCHECK_NE(state
, next_state
);
117 failure_injection_state_
= state
;
118 failure_injection_next_state_
= next_state
;
119 fault_response_
= response
;
122 State
state() const {
126 void Reset() override
{
127 DynamicSocketDataProvider::Reset();
131 void set_multiline_welcome(bool multiline
) { multiline_welcome_
= multiline
; }
133 bool use_epsv() const { return use_epsv_
; }
134 void set_use_epsv(bool use_epsv
) { use_epsv_
= use_epsv
; }
136 void set_data_type(char data_type
) { data_type_
= data_type
; }
141 SimulateRead("220 host TestFTPd\r\n");
144 // If protocol fault injection has been requested, adjusts state and mocked
145 // read and returns true.
147 if (state_
!= failure_injection_state_
)
149 SimulateRead(fault_response_
);
150 state_
= failure_injection_next_state_
;
154 MockWriteResult
Verify(const std::string
& expected
,
155 const std::string
& data
,
157 const char* next_read
,
158 const size_t next_read_length
) {
159 EXPECT_EQ(expected
, data
);
160 if (expected
== data
) {
162 SimulateRead(next_read
, next_read_length
);
163 return MockWriteResult(ASYNC
, data
.length());
165 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
168 MockWriteResult
Verify(const std::string
& expected
,
169 const std::string
& data
,
171 const char* next_read
) {
172 return Verify(expected
, data
, next_state
,
173 next_read
, std::strlen(next_read
));
179 State failure_injection_state_
;
180 State failure_injection_next_state_
;
181 const char* fault_response_
;
183 // If true, we will send multiple 230 lines as response after PASS.
184 bool multiline_welcome_
;
186 // If true, we will use EPSV command.
189 // Data type to be used for TYPE command.
192 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider
);
195 class FtpSocketDataProviderDirectoryListing
: public FtpSocketDataProvider
{
197 FtpSocketDataProviderDirectoryListing() {
200 MockWriteResult
OnWrite(const std::string
& data
) override
{
202 return MockWriteResult(ASYNC
, data
.length());
205 return Verify("SIZE /\r\n", data
, PRE_CWD
,
206 "550 I can only retrieve regular files\r\n");
208 return Verify("CWD /\r\n", data
,
209 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
211 return Verify("LIST -l\r\n", data
, PRE_QUIT
, "200 OK\r\n");
213 return FtpSocketDataProvider::OnWrite(data
);
218 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing
);
221 class FtpSocketDataProviderDirectoryListingWithPasvFallback
222 : public FtpSocketDataProviderDirectoryListing
{
224 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
227 MockWriteResult
OnWrite(const std::string
& data
) override
{
229 return MockWriteResult(ASYNC
, data
.length());
232 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
233 "500 no EPSV for you\r\n");
235 return Verify("SIZE /\r\n", data
, PRE_CWD
,
236 "550 I can only retrieve regular files\r\n");
238 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
243 DISALLOW_COPY_AND_ASSIGN(
244 FtpSocketDataProviderDirectoryListingWithPasvFallback
);
247 class FtpSocketDataProviderDirectoryListingZeroSize
248 : public FtpSocketDataProviderDirectoryListing
{
250 FtpSocketDataProviderDirectoryListingZeroSize() {
253 MockWriteResult
OnWrite(const std::string
& data
) override
{
255 return MockWriteResult(ASYNC
, data
.length());
258 return Verify("SIZE /\r\n", data
, PRE_CWD
, "213 0\r\n");
260 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
265 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize
);
268 class FtpSocketDataProviderVMSDirectoryListing
: public FtpSocketDataProvider
{
270 FtpSocketDataProviderVMSDirectoryListing() {
273 MockWriteResult
OnWrite(const std::string
& data
) override
{
275 return MockWriteResult(ASYNC
, data
.length());
278 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
280 return Verify("PWD\r\n", data
, PRE_TYPE
,
281 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
283 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
284 "500 Invalid command\r\n");
286 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data
, PRE_CWD
,
287 "550 I can only retrieve regular files\r\n");
289 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data
,
290 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
292 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
294 return FtpSocketDataProvider::OnWrite(data
);
299 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing
);
302 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
303 : public FtpSocketDataProvider
{
305 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
308 MockWriteResult
OnWrite(const std::string
& data
) override
{
310 return MockWriteResult(ASYNC
, data
.length());
313 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
315 return Verify("PWD\r\n", data
, PRE_TYPE
,
316 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
318 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
319 "500 EPSV command unknown\r\n");
321 return Verify("SIZE ANONYMOUS_ROOT\r\n", data
, PRE_CWD
,
322 "550 I can only retrieve regular files\r\n");
324 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data
,
325 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
327 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
329 return FtpSocketDataProvider::OnWrite(data
);
334 DISALLOW_COPY_AND_ASSIGN(
335 FtpSocketDataProviderVMSDirectoryListingRootDirectory
);
338 class FtpSocketDataProviderFileDownloadWithFileTypecode
339 : public FtpSocketDataProvider
{
341 FtpSocketDataProviderFileDownloadWithFileTypecode() {
344 MockWriteResult
OnWrite(const std::string
& data
) override
{
346 return MockWriteResult(ASYNC
, data
.length());
349 return Verify("SIZE /file\r\n", data
,
350 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
, "213 18\r\n");
352 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
354 return FtpSocketDataProvider::OnWrite(data
);
359 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode
);
362 class FtpSocketDataProviderFileDownload
: public FtpSocketDataProvider
{
364 FtpSocketDataProviderFileDownload() {
367 MockWriteResult
OnWrite(const std::string
& data
) override
{
369 return MockWriteResult(ASYNC
, data
.length());
372 return Verify("SIZE /file\r\n", data
, PRE_CWD
, "213 18\r\n");
374 return Verify("CWD /file\r\n", data
,
375 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
376 "550 Not a directory\r\n");
378 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
380 return FtpSocketDataProvider::OnWrite(data
);
385 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload
);
388 class FtpSocketDataProviderFileNotFound
: public FtpSocketDataProvider
{
390 FtpSocketDataProviderFileNotFound() {
393 MockWriteResult
OnWrite(const std::string
& data
) override
{
395 return MockWriteResult(ASYNC
, data
.length());
398 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
399 "550 File Not Found\r\n");
401 return Verify("CWD /file\r\n", data
,
402 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
403 "550 File Not Found\r\n");
405 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
406 "550 File Not Found\r\n");
408 return FtpSocketDataProvider::OnWrite(data
);
413 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound
);
416 class FtpSocketDataProviderFileDownloadWithPasvFallback
417 : public FtpSocketDataProviderFileDownload
{
419 FtpSocketDataProviderFileDownloadWithPasvFallback() {
422 MockWriteResult
OnWrite(const std::string
& data
) override
{
424 return MockWriteResult(ASYNC
, data
.length());
427 return Verify("EPSV\r\n", data
, PRE_RETR_PASV
, "500 No can do\r\n");
429 return Verify("CWD /file\r\n", data
,
430 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
431 "550 Not a directory\r\n");
433 return FtpSocketDataProviderFileDownload::OnWrite(data
);
438 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback
);
441 class FtpSocketDataProviderFileDownloadZeroSize
442 : public FtpSocketDataProviderFileDownload
{
444 FtpSocketDataProviderFileDownloadZeroSize() {
447 MockWriteResult
OnWrite(const std::string
& data
) override
{
449 return MockWriteResult(ASYNC
, data
.length());
452 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
455 return Verify("CWD /file\r\n", data
,
456 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
457 "550 not a directory\r\n");
459 return FtpSocketDataProviderFileDownload::OnWrite(data
);
464 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize
);
467 class FtpSocketDataProviderFileDownloadCWD451
468 : public FtpSocketDataProviderFileDownload
{
470 FtpSocketDataProviderFileDownloadCWD451() {
473 MockWriteResult
OnWrite(const std::string
& data
) override
{
475 return MockWriteResult(ASYNC
, data
.length());
478 return Verify("CWD /file\r\n", data
,
479 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
480 "451 not a directory\r\n");
482 return FtpSocketDataProviderFileDownload::OnWrite(data
);
487 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451
);
490 class FtpSocketDataProviderVMSFileDownload
: public FtpSocketDataProvider
{
492 FtpSocketDataProviderVMSFileDownload() {
495 MockWriteResult
OnWrite(const std::string
& data
) override
{
497 return MockWriteResult(ASYNC
, data
.length());
500 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
502 return Verify("PWD\r\n", data
, PRE_TYPE
,
503 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
505 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
506 "500 EPSV command unknown\r\n");
508 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_CWD
,
511 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data
,
512 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
513 "550 Not a directory\r\n");
515 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_QUIT
,
518 return FtpSocketDataProvider::OnWrite(data
);
523 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload
);
526 class FtpSocketDataProviderEscaping
: public FtpSocketDataProviderFileDownload
{
528 FtpSocketDataProviderEscaping() {
531 MockWriteResult
OnWrite(const std::string
& data
) override
{
533 return MockWriteResult(ASYNC
, data
.length());
536 return Verify("SIZE / !\"#$%y\200\201\r\n", data
, PRE_CWD
,
539 return Verify("CWD / !\"#$%y\200\201\r\n", data
,
540 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
541 "550 Not a directory\r\n");
543 return Verify("RETR / !\"#$%y\200\201\r\n", data
, PRE_QUIT
,
546 return FtpSocketDataProviderFileDownload::OnWrite(data
);
551 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping
);
554 class FtpSocketDataProviderFileDownloadTransferStarting
555 : public FtpSocketDataProviderFileDownload
{
557 FtpSocketDataProviderFileDownloadTransferStarting() {
560 MockWriteResult
OnWrite(const std::string
& data
) override
{
562 return MockWriteResult(ASYNC
, data
.length());
565 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
566 "125-Data connection already open.\r\n"
567 "125 Transfer starting.\r\n"
568 "226 Transfer complete.\r\n");
570 return FtpSocketDataProviderFileDownload::OnWrite(data
);
575 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting
);
578 class FtpSocketDataProviderDirectoryListingTransferStarting
579 : public FtpSocketDataProviderDirectoryListing
{
581 FtpSocketDataProviderDirectoryListingTransferStarting() {
584 MockWriteResult
OnWrite(const std::string
& data
) override
{
586 return MockWriteResult(ASYNC
, data
.length());
589 return Verify("LIST -l\r\n", data
, PRE_QUIT
,
590 "125-Data connection already open.\r\n"
591 "125 Transfer starting.\r\n"
592 "226 Transfer complete.\r\n");
594 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
599 DISALLOW_COPY_AND_ASSIGN(
600 FtpSocketDataProviderDirectoryListingTransferStarting
);
603 class FtpSocketDataProviderFileDownloadInvalidResponse
604 : public FtpSocketDataProviderFileDownload
{
606 FtpSocketDataProviderFileDownloadInvalidResponse() {
609 MockWriteResult
OnWrite(const std::string
& data
) override
{
611 return MockWriteResult(ASYNC
, data
.length());
614 // Use unallocated 599 FTP error code to make sure it falls into the
615 // generic ERR_FTP_FAILED bucket.
616 return Verify("SIZE /file\r\n", data
, PRE_QUIT
,
617 "599 Evil Response\r\n"
618 "599 More Evil\r\n");
620 return FtpSocketDataProviderFileDownload::OnWrite(data
);
625 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse
);
628 class FtpSocketDataProviderEvilEpsv
: public FtpSocketDataProviderFileDownload
{
630 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
631 State expected_state
)
632 : epsv_response_(epsv_response
),
633 epsv_response_length_(std::strlen(epsv_response
)),
634 expected_state_(expected_state
) {}
636 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
637 size_t epsv_response_length
,
638 State expected_state
)
639 : epsv_response_(epsv_response
),
640 epsv_response_length_(epsv_response_length
),
641 expected_state_(expected_state
) {}
643 MockWriteResult
OnWrite(const std::string
& data
) override
{
645 return MockWriteResult(ASYNC
, data
.length());
648 return Verify("EPSV\r\n", data
, expected_state_
,
649 epsv_response_
, epsv_response_length_
);
651 return FtpSocketDataProviderFileDownload::OnWrite(data
);
656 const char* epsv_response_
;
657 const size_t epsv_response_length_
;
658 const State expected_state_
;
660 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv
);
663 class FtpSocketDataProviderEvilPasv
664 : public FtpSocketDataProviderFileDownloadWithPasvFallback
{
666 FtpSocketDataProviderEvilPasv(const char* pasv_response
, State expected_state
)
667 : pasv_response_(pasv_response
),
668 expected_state_(expected_state
) {
671 MockWriteResult
OnWrite(const std::string
& data
) override
{
673 return MockWriteResult(ASYNC
, data
.length());
676 return Verify("PASV\r\n", data
, expected_state_
, pasv_response_
);
678 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data
);
683 const char* pasv_response_
;
684 const State expected_state_
;
686 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv
);
689 class FtpSocketDataProviderEvilSize
: public FtpSocketDataProviderFileDownload
{
691 FtpSocketDataProviderEvilSize(const char* size_response
, State expected_state
)
692 : size_response_(size_response
),
693 expected_state_(expected_state
) {
696 MockWriteResult
OnWrite(const std::string
& data
) override
{
698 return MockWriteResult(ASYNC
, data
.length());
701 return Verify("SIZE /file\r\n", data
, expected_state_
, size_response_
);
703 return FtpSocketDataProviderFileDownload::OnWrite(data
);
708 const char* size_response_
;
709 const State expected_state_
;
711 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize
);
714 class FtpSocketDataProviderEvilLogin
715 : public FtpSocketDataProviderFileDownload
{
717 FtpSocketDataProviderEvilLogin(const char* expected_user
,
718 const char* expected_password
)
719 : expected_user_(expected_user
),
720 expected_password_(expected_password
) {
723 MockWriteResult
OnWrite(const std::string
& data
) override
{
725 return MockWriteResult(ASYNC
, data
.length());
728 return Verify(std::string("USER ") + expected_user_
+ "\r\n", data
,
729 PRE_PASSWD
, "331 Password needed\r\n");
731 return Verify(std::string("PASS ") + expected_password_
+ "\r\n", data
,
732 PRE_SYST
, "230 Welcome\r\n");
734 return FtpSocketDataProviderFileDownload::OnWrite(data
);
739 const char* expected_user_
;
740 const char* expected_password_
;
742 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin
);
745 class FtpSocketDataProviderCloseConnection
: public FtpSocketDataProvider
{
747 FtpSocketDataProviderCloseConnection() {
750 MockWriteResult
OnWrite(const std::string
& data
) override
{
752 return MockWriteResult(ASYNC
, data
.length());
755 return Verify("USER anonymous\r\n", data
,
758 return FtpSocketDataProvider::OnWrite(data
);
763 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection
);
766 class FtpNetworkTransactionTest
767 : public PlatformTest
,
768 public ::testing::WithParamInterface
<int> {
770 FtpNetworkTransactionTest()
771 : host_resolver_(new MockHostResolver
),
772 session_(new FtpNetworkSession(host_resolver_
.get())),
773 transaction_(session_
.get(), &mock_socket_factory_
) {
774 scoped_refptr
<RuleBasedHostResolverProc
> rules(
775 new RuleBasedHostResolverProc(NULL
));
776 if (GetFamily() == AF_INET
) {
777 rules
->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
778 } else if (GetFamily() == AF_INET6
) {
779 rules
->AddIPLiteralRule("*", "::1", "::1");
783 host_resolver_
->set_rules(rules
.get());
787 // Accessor to make code refactoring-friendly, e.g. when we change the way
788 // parameters are passed (like more parameters).
793 FtpRequestInfo
GetRequestInfo(const std::string
& url
) {
795 info
.url
= GURL(url
);
799 void ExecuteTransaction(FtpSocketDataProvider
* ctrl_socket
,
801 int expected_result
) {
802 // Expect EPSV usage for non-IPv4 control connections.
803 ctrl_socket
->set_use_epsv((GetFamily() != AF_INET
));
805 mock_socket_factory_
.AddSocketDataProvider(ctrl_socket
);
807 std::string
mock_data("mock-data");
808 MockRead data_reads
[] = {
809 // Usually FTP servers close the data connection after the entire data has
811 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
812 MockRead(mock_data
.c_str()),
815 scoped_ptr
<StaticSocketDataProvider
> data_socket(
816 new StaticSocketDataProvider(data_reads
, arraysize(data_reads
), NULL
,
818 mock_socket_factory_
.AddSocketDataProvider(data_socket
.get());
819 FtpRequestInfo request_info
= GetRequestInfo(request
);
820 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
821 ASSERT_EQ(ERR_IO_PENDING
,
822 transaction_
.Start(&request_info
, callback_
.callback(),
824 EXPECT_NE(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
825 ASSERT_EQ(expected_result
, callback_
.WaitForResult());
826 if (expected_result
== OK
) {
827 scoped_refptr
<IOBuffer
> io_buffer(new IOBuffer(kBufferSize
));
828 memset(io_buffer
->data(), 0, kBufferSize
);
829 ASSERT_EQ(ERR_IO_PENDING
,
830 transaction_
.Read(io_buffer
.get(), kBufferSize
,
831 callback_
.callback()));
832 ASSERT_EQ(static_cast<int>(mock_data
.length()),
833 callback_
.WaitForResult());
834 EXPECT_EQ(mock_data
, std::string(io_buffer
->data(), mock_data
.length()));
836 // Do another Read to detect that the data socket is now closed.
837 int rv
= transaction_
.Read(io_buffer
.get(), kBufferSize
,
838 callback_
.callback());
839 if (rv
== ERR_IO_PENDING
) {
840 EXPECT_EQ(0, callback_
.WaitForResult());
845 EXPECT_EQ(FtpSocketDataProvider::QUIT
, ctrl_socket
->state());
846 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
849 void TransactionFailHelper(FtpSocketDataProvider
* ctrl_socket
,
851 FtpSocketDataProvider::State state
,
852 FtpSocketDataProvider::State next_state
,
853 const char* response
,
854 int expected_result
) {
855 ctrl_socket
->InjectFailure(state
, next_state
, response
);
856 ExecuteTransaction(ctrl_socket
, request
, expected_result
);
859 scoped_ptr
<MockHostResolver
> host_resolver_
;
860 scoped_refptr
<FtpNetworkSession
> session_
;
861 MockClientSocketFactory mock_socket_factory_
;
862 FtpNetworkTransaction transaction_
;
863 TestCompletionCallback callback_
;
866 TEST_P(FtpNetworkTransactionTest
, FailedLookup
) {
867 FtpRequestInfo request_info
= GetRequestInfo("ftp://badhost");
868 scoped_refptr
<RuleBasedHostResolverProc
> rules(
869 new RuleBasedHostResolverProc(NULL
));
870 rules
->AddSimulatedFailure("badhost");
871 host_resolver_
->set_rules(rules
.get());
873 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
874 ASSERT_EQ(ERR_IO_PENDING
,
875 transaction_
.Start(&request_info
, callback_
.callback(),
877 ASSERT_EQ(ERR_NAME_NOT_RESOLVED
, callback_
.WaitForResult());
878 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
881 // Check that when determining the host, the square brackets decorating IPv6
882 // literals in URLs are stripped.
883 TEST_P(FtpNetworkTransactionTest
, StripBracketsFromIPv6Literals
) {
884 // This test only makes sense for IPv6 connections.
885 if (GetFamily() != AF_INET6
)
888 host_resolver_
->rules()->AddSimulatedFailure("[::1]");
890 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
891 // The important part of this test is to make sure that we don't fail with
892 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
894 FtpSocketDataProviderEvilSize
ctrl_socket(
895 "213 99999999999999999999999999999999\r\n",
896 FtpSocketDataProvider::PRE_QUIT
);
897 ExecuteTransaction(&ctrl_socket
, "ftp://[::1]/file", ERR_INVALID_RESPONSE
);
900 TEST_P(FtpNetworkTransactionTest
, DirectoryTransaction
) {
901 FtpSocketDataProviderDirectoryListing ctrl_socket
;
902 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
904 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
905 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
906 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
907 transaction_
.GetResponseInfo()->socket_address
.host());
908 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
911 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithPasvFallback
) {
912 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket
;
913 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
915 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
916 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
919 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithTypecode
) {
920 FtpSocketDataProviderDirectoryListing ctrl_socket
;
921 ExecuteTransaction(&ctrl_socket
, "ftp://host/;type=d", OK
);
923 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
924 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
927 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcome
) {
928 FtpSocketDataProviderDirectoryListing ctrl_socket
;
929 ctrl_socket
.set_multiline_welcome(true);
930 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
933 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads2
) {
934 FtpSocketDataProviderDirectoryListing ctrl_socket
;
935 ctrl_socket
.set_short_read_limit(2);
936 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
939 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads5
) {
940 FtpSocketDataProviderDirectoryListing ctrl_socket
;
941 ctrl_socket
.set_short_read_limit(5);
942 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
945 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcomeShort
) {
946 FtpSocketDataProviderDirectoryListing ctrl_socket
;
947 // The client will not consume all three 230 lines. That's good, we want to
948 // test that scenario.
949 ctrl_socket
.allow_unconsumed_reads(true);
950 ctrl_socket
.set_multiline_welcome(true);
951 ctrl_socket
.set_short_read_limit(5);
952 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
955 // Regression test for http://crbug.com/60555.
956 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionZeroSize
) {
957 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket
;
958 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
961 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMS
) {
962 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
963 ExecuteTransaction(&ctrl_socket
, "ftp://host/dir", OK
);
966 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMSRootDirectory
) {
967 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket
;
968 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
971 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionTransferStarting
) {
972 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket
;
973 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
976 TEST_P(FtpNetworkTransactionTest
, DownloadTransaction
) {
977 FtpSocketDataProviderFileDownload ctrl_socket
;
978 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
980 // We pass an artificial value of 18 as a response to the SIZE command.
981 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
982 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
983 transaction_
.GetResponseInfo()->socket_address
.host());
984 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
987 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithPasvFallback
) {
988 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket
;
989 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
991 // We pass an artificial value of 18 as a response to the SIZE command.
992 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
995 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeA
) {
996 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
997 ctrl_socket
.set_data_type('A');
998 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=a", OK
);
1000 // We pass an artificial value of 18 as a response to the SIZE command.
1001 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1004 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeI
) {
1005 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1006 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=i", OK
);
1008 // We pass an artificial value of 18 as a response to the SIZE command.
1009 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1012 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionMultilineWelcome
) {
1013 FtpSocketDataProviderFileDownload ctrl_socket
;
1014 ctrl_socket
.set_multiline_welcome(true);
1015 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1018 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads2
) {
1019 FtpSocketDataProviderFileDownload ctrl_socket
;
1020 ctrl_socket
.set_short_read_limit(2);
1021 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1024 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads5
) {
1025 FtpSocketDataProviderFileDownload ctrl_socket
;
1026 ctrl_socket
.set_short_read_limit(5);
1027 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1030 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionZeroSize
) {
1031 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket
;
1032 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1035 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionCWD451
) {
1036 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket
;
1037 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1040 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionVMS
) {
1041 FtpSocketDataProviderVMSFileDownload ctrl_socket
;
1042 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1045 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionTransferStarting
) {
1046 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket
;
1047 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1050 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionInvalidResponse
) {
1051 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket
;
1052 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1055 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvReallyBadFormat
) {
1056 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,\r\n",
1057 FtpSocketDataProvider::PRE_QUIT
);
1058 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1061 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort1
) {
1062 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1063 FtpSocketDataProvider::PRE_QUIT
);
1064 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1067 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort2
) {
1068 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1069 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1070 FtpSocketDataProvider::PRE_QUIT
);
1071 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1074 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort3
) {
1075 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1076 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1077 FtpSocketDataProvider::PRE_QUIT
);
1078 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1081 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort4
) {
1082 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1083 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1084 FtpSocketDataProvider::PRE_QUIT
);
1085 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1088 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafeHost
) {
1089 FtpSocketDataProviderEvilPasv
ctrl_socket(
1090 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR
);
1091 ctrl_socket
.set_use_epsv(GetFamily() != AF_INET
);
1092 std::string
mock_data("mock-data");
1093 MockRead data_reads
[] = {
1094 MockRead(mock_data
.c_str()),
1096 StaticSocketDataProvider data_socket1
;
1097 StaticSocketDataProvider
data_socket2(data_reads
, arraysize(data_reads
),
1099 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket
);
1100 mock_socket_factory_
.AddSocketDataProvider(&data_socket1
);
1101 mock_socket_factory_
.AddSocketDataProvider(&data_socket2
);
1102 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1104 // Start the transaction.
1105 ASSERT_EQ(ERR_IO_PENDING
,
1106 transaction_
.Start(&request_info
, callback_
.callback(),
1108 ASSERT_EQ(OK
, callback_
.WaitForResult());
1110 // The transaction fires the callback when we can start reading data. That
1111 // means that the data socket should be open.
1112 MockTCPClientSocket
* data_socket
=
1113 static_cast<MockTCPClientSocket
*>(transaction_
.data_socket_
.get());
1114 ASSERT_TRUE(data_socket
);
1115 ASSERT_TRUE(data_socket
->IsConnected());
1117 // Even if the PASV response specified some other address, we connect
1118 // to the address we used for control connection (which could be 127.0.0.1
1119 // or ::1 depending on whether we use IPv6).
1120 for (AddressList::const_iterator it
= data_socket
->addresses().begin();
1121 it
!= data_socket
->addresses().end(); ++it
) {
1122 EXPECT_NE("10.1.2.3", it
->ToStringWithoutPort());
1126 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat1
) {
1127 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1128 if (GetFamily() == AF_INET
)
1131 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22)\r\n",
1132 FtpSocketDataProvider::PRE_QUIT
);
1133 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1136 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat2
) {
1137 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1138 if (GetFamily() == AF_INET
)
1141 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||\r\n",
1142 FtpSocketDataProvider::PRE_QUIT
);
1143 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1146 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat3
) {
1147 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1148 if (GetFamily() == AF_INET
)
1151 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan\r\n",
1152 FtpSocketDataProvider::PRE_QUIT
);
1153 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1156 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat4
) {
1157 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1158 if (GetFamily() == AF_INET
)
1161 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||||)\r\n",
1162 FtpSocketDataProvider::PRE_QUIT
);
1163 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1166 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat5
) {
1167 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1168 if (GetFamily() == AF_INET
)
1171 // Breaking the string in the next line prevents MSVC warning C4125.
1172 const char response
[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1173 FtpSocketDataProviderEvilEpsv
ctrl_socket(response
, sizeof(response
)-1,
1174 FtpSocketDataProvider::PRE_QUIT
);
1175 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1178 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort1
) {
1179 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1180 if (GetFamily() == AF_INET
)
1183 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22|)\r\n",
1184 FtpSocketDataProvider::PRE_QUIT
);
1185 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1188 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort2
) {
1189 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1190 if (GetFamily() == AF_INET
)
1193 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||258|)\r\n",
1194 FtpSocketDataProvider::PRE_QUIT
);
1195 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1198 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort3
) {
1199 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1200 if (GetFamily() == AF_INET
)
1203 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||772|)\r\n",
1204 FtpSocketDataProvider::PRE_QUIT
);
1205 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1208 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort4
) {
1209 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1210 if (GetFamily() == AF_INET
)
1213 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||2049|)\r\n",
1214 FtpSocketDataProvider::PRE_QUIT
);
1215 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1218 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvWeirdSep
) {
1219 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1220 if (GetFamily() == AF_INET
)
1223 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$31744$)\r\n",
1224 FtpSocketDataProvider::PRE_RETR
);
1225 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1228 TEST_P(FtpNetworkTransactionTest
,
1229 DownloadTransactionEvilEpsvWeirdSepUnsafePort
) {
1230 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1231 if (GetFamily() == AF_INET
)
1234 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$317$)\r\n",
1235 FtpSocketDataProvider::PRE_QUIT
);
1236 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1239 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvIllegalHost
) {
1240 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1241 if (GetFamily() == AF_INET
)
1244 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1245 FtpSocketDataProvider::PRE_QUIT
);
1246 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1249 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadUsername
) {
1250 FtpSocketDataProviderEvilLogin
ctrl_socket("hello%0Aworld", "test");
1251 ExecuteTransaction(&ctrl_socket
, "ftp://hello%0Aworld:test@host/file", OK
);
1254 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadPassword
) {
1255 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello%0Dworld");
1256 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%0Dworld@host/file", OK
);
1259 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInLogin
) {
1260 FtpSocketDataProviderEvilLogin
ctrl_socket("hello world", "test");
1261 ExecuteTransaction(&ctrl_socket
, "ftp://hello%20world:test@host/file", OK
);
1264 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInPassword
) {
1265 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello world");
1266 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%20world@host/file", OK
);
1269 TEST_P(FtpNetworkTransactionTest
, EvilRestartUser
) {
1270 FtpSocketDataProvider ctrl_socket1
;
1271 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1272 FtpSocketDataProvider::PRE_QUIT
,
1273 "530 Login authentication failed\r\n");
1274 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1276 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1278 ASSERT_EQ(ERR_IO_PENDING
,
1279 transaction_
.Start(&request_info
, callback_
.callback(),
1281 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1283 MockRead ctrl_reads
[] = {
1284 MockRead("220 host TestFTPd\r\n"),
1285 MockRead("221 Goodbye!\r\n"),
1286 MockRead(SYNCHRONOUS
, OK
),
1288 MockWrite ctrl_writes
[] = {
1289 MockWrite("QUIT\r\n"),
1291 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1292 ctrl_writes
, arraysize(ctrl_writes
));
1293 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1294 ASSERT_EQ(ERR_IO_PENDING
,
1295 transaction_
.RestartWithAuth(
1297 base::ASCIIToUTF16("foo\nownz0red"),
1298 base::ASCIIToUTF16("innocent")),
1299 callback_
.callback()));
1300 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1303 TEST_P(FtpNetworkTransactionTest
, EvilRestartPassword
) {
1304 FtpSocketDataProvider ctrl_socket1
;
1305 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1306 FtpSocketDataProvider::PRE_QUIT
,
1307 "530 Login authentication failed\r\n");
1308 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1310 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1312 ASSERT_EQ(ERR_IO_PENDING
,
1313 transaction_
.Start(&request_info
, callback_
.callback(),
1315 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1317 MockRead ctrl_reads
[] = {
1318 MockRead("220 host TestFTPd\r\n"),
1319 MockRead("331 User okay, send password\r\n"),
1320 MockRead("221 Goodbye!\r\n"),
1321 MockRead(SYNCHRONOUS
, OK
),
1323 MockWrite ctrl_writes
[] = {
1324 MockWrite("USER innocent\r\n"),
1325 MockWrite("QUIT\r\n"),
1327 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1328 ctrl_writes
, arraysize(ctrl_writes
));
1329 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1330 ASSERT_EQ(ERR_IO_PENDING
,
1331 transaction_
.RestartWithAuth(
1332 AuthCredentials(base::ASCIIToUTF16("innocent"),
1333 base::ASCIIToUTF16("foo\nownz0red")),
1334 callback_
.callback()));
1335 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1338 TEST_P(FtpNetworkTransactionTest
, Escaping
) {
1339 FtpSocketDataProviderEscaping ctrl_socket
;
1340 ExecuteTransaction(&ctrl_socket
, "ftp://host/%20%21%22%23%24%25%79%80%81",
1344 // Test for http://crbug.com/23794.
1345 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilSize
) {
1346 // Try to overflow int64 in the response.
1347 FtpSocketDataProviderEvilSize
ctrl_socket(
1348 "213 99999999999999999999999999999999\r\n",
1349 FtpSocketDataProvider::PRE_QUIT
);
1350 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1353 // Test for http://crbug.com/36360.
1354 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionBigSize
) {
1355 // Pass a valid, but large file size. The transaction should not fail.
1356 FtpSocketDataProviderEvilSize
ctrl_socket(
1357 "213 3204427776\r\n",
1358 FtpSocketDataProvider::PRE_CWD
);
1359 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1360 EXPECT_EQ(3204427776LL,
1361 transaction_
.GetResponseInfo()->expected_content_size
);
1364 // Regression test for http://crbug.com/25023.
1365 TEST_P(FtpNetworkTransactionTest
, CloseConnection
) {
1366 FtpSocketDataProviderCloseConnection ctrl_socket
;
1367 ExecuteTransaction(&ctrl_socket
, "ftp://host", ERR_EMPTY_RESPONSE
);
1370 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailUser
) {
1371 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1372 // Use unallocated 599 FTP error code to make sure it falls into the generic
1373 // ERR_FTP_FAILED bucket.
1374 TransactionFailHelper(&ctrl_socket
,
1376 FtpSocketDataProvider::PRE_USER
,
1377 FtpSocketDataProvider::PRE_QUIT
,
1382 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass
) {
1383 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1384 TransactionFailHelper(&ctrl_socket
,
1386 FtpSocketDataProvider::PRE_PASSWD
,
1387 FtpSocketDataProvider::PRE_QUIT
,
1388 "530 Login authentication failed\r\n",
1392 // Regression test for http://crbug.com/38707.
1393 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass503
) {
1394 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1395 TransactionFailHelper(&ctrl_socket
,
1397 FtpSocketDataProvider::PRE_PASSWD
,
1398 FtpSocketDataProvider::PRE_QUIT
,
1399 "503 Bad sequence of commands\r\n",
1400 ERR_FTP_BAD_COMMAND_SEQUENCE
);
1403 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailSyst
) {
1404 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1405 // Use unallocated 599 FTP error code to make sure it falls into the generic
1406 // ERR_FTP_FAILED bucket.
1407 TransactionFailHelper(&ctrl_socket
,
1409 FtpSocketDataProvider::PRE_SYST
,
1410 FtpSocketDataProvider::PRE_PWD
,
1415 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPwd
) {
1416 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1417 // Use unallocated 599 FTP error code to make sure it falls into the generic
1418 // ERR_FTP_FAILED bucket.
1419 TransactionFailHelper(&ctrl_socket
,
1421 FtpSocketDataProvider::PRE_PWD
,
1422 FtpSocketDataProvider::PRE_QUIT
,
1427 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailType
) {
1428 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1429 // Use unallocated 599 FTP error code to make sure it falls into the generic
1430 // ERR_FTP_FAILED bucket.
1431 TransactionFailHelper(&ctrl_socket
,
1433 FtpSocketDataProvider::PRE_TYPE
,
1434 FtpSocketDataProvider::PRE_QUIT
,
1439 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailEpsv
) {
1440 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1441 if (GetFamily() == AF_INET
)
1444 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1445 // Use unallocated 599 FTP error code to make sure it falls into the generic
1446 // ERR_FTP_FAILED bucket.
1447 TransactionFailHelper(
1448 &ctrl_socket
, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV
,
1449 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1452 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailCwd
) {
1453 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1454 // Use unallocated 599 FTP error code to make sure it falls into the generic
1455 // ERR_FTP_FAILED bucket.
1456 TransactionFailHelper(&ctrl_socket
,
1458 FtpSocketDataProvider::PRE_CWD
,
1459 FtpSocketDataProvider::PRE_QUIT
,
1464 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailList
) {
1465 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1466 // Use unallocated 599 FTP error code to make sure it falls into the generic
1467 // ERR_FTP_FAILED bucket.
1468 TransactionFailHelper(&ctrl_socket
,
1470 FtpSocketDataProvider::PRE_LIST
,
1471 FtpSocketDataProvider::PRE_QUIT
,
1476 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailUser
) {
1477 FtpSocketDataProviderFileDownload ctrl_socket
;
1478 // Use unallocated 599 FTP error code to make sure it falls into the generic
1479 // ERR_FTP_FAILED bucket.
1480 TransactionFailHelper(&ctrl_socket
,
1482 FtpSocketDataProvider::PRE_USER
,
1483 FtpSocketDataProvider::PRE_QUIT
,
1488 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPass
) {
1489 FtpSocketDataProviderFileDownload ctrl_socket
;
1490 TransactionFailHelper(&ctrl_socket
,
1492 FtpSocketDataProvider::PRE_PASSWD
,
1493 FtpSocketDataProvider::PRE_QUIT
,
1494 "530 Login authentication failed\r\n",
1498 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailSyst
) {
1499 FtpSocketDataProviderFileDownload ctrl_socket
;
1500 // Use unallocated 599 FTP error code to make sure it falls into the generic
1501 // ERR_FTP_FAILED bucket.
1502 TransactionFailHelper(&ctrl_socket
,
1504 FtpSocketDataProvider::PRE_SYST
,
1505 FtpSocketDataProvider::PRE_PWD
,
1510 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPwd
) {
1511 FtpSocketDataProviderFileDownload ctrl_socket
;
1512 // Use unallocated 599 FTP error code to make sure it falls into the generic
1513 // ERR_FTP_FAILED bucket.
1514 TransactionFailHelper(&ctrl_socket
,
1516 FtpSocketDataProvider::PRE_PWD
,
1517 FtpSocketDataProvider::PRE_QUIT
,
1522 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailType
) {
1523 FtpSocketDataProviderFileDownload ctrl_socket
;
1524 // Use unallocated 599 FTP error code to make sure it falls into the generic
1525 // ERR_FTP_FAILED bucket.
1526 TransactionFailHelper(&ctrl_socket
,
1528 FtpSocketDataProvider::PRE_TYPE
,
1529 FtpSocketDataProvider::PRE_QUIT
,
1534 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailEpsv
) {
1535 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1536 if (GetFamily() == AF_INET
)
1539 FtpSocketDataProviderFileDownload ctrl_socket
;
1540 // Use unallocated 599 FTP error code to make sure it falls into the generic
1541 // ERR_FTP_FAILED bucket.
1542 TransactionFailHelper(
1543 &ctrl_socket
, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV
,
1544 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1547 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailRetr
) {
1548 FtpSocketDataProviderFileDownload ctrl_socket
;
1549 // Use unallocated 599 FTP error code to make sure it falls into the generic
1550 // ERR_FTP_FAILED bucket.
1551 TransactionFailHelper(&ctrl_socket
,
1553 FtpSocketDataProvider::PRE_RETR
,
1554 FtpSocketDataProvider::PRE_QUIT
,
1559 TEST_P(FtpNetworkTransactionTest
, FileNotFound
) {
1560 FtpSocketDataProviderFileNotFound ctrl_socket
;
1561 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_FTP_FAILED
);
1564 // Test for http://crbug.com/38845.
1565 TEST_P(FtpNetworkTransactionTest
, ZeroLengthDirInPWD
) {
1566 FtpSocketDataProviderFileDownload ctrl_socket
;
1567 TransactionFailHelper(&ctrl_socket
,
1569 FtpSocketDataProvider::PRE_PWD
,
1570 FtpSocketDataProvider::PRE_TYPE
,
1575 INSTANTIATE_TEST_CASE_P(FTP
,
1576 FtpNetworkTransactionTest
,
1577 ::testing::Values(AF_INET
, AF_INET6
));