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
{
58 FtpSocketDataProvider()
59 : failure_injection_state_(NONE
),
60 multiline_welcome_(false),
66 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
68 return MockWriteResult(ASYNC
, data
.length());
71 return Verify("USER anonymous\r\n", data
, PRE_PASSWD
,
72 "331 Password needed\r\n");
75 const char* response_one
= "230 Welcome\r\n";
76 const char* response_multi
= "230- One\r\n230- Two\r\n230 Three\r\n";
77 return Verify("PASS chrome@example.com\r\n", data
, PRE_SYST
,
78 multiline_welcome_
? response_multi
: response_one
);
81 return Verify("SYST\r\n", data
, PRE_PWD
, "215 UNIX\r\n");
83 return Verify("PWD\r\n", data
, PRE_TYPE
,
84 "257 \"/\" is your current location\r\n");
86 return Verify(std::string("TYPE ") + data_type_
+ "\r\n", data
,
87 use_epsv_
? PRE_EPSV
: PRE_PASV
,
88 "200 TYPE set successfully\r\n");
90 return Verify("EPSV\r\n", data
, PRE_SIZE
,
91 "227 Entering Extended Passive Mode (|||31744|)\r\n");
93 return Verify("EPSV\r\n", data
, PRE_CWD
,
94 "227 Entering Extended Passive Mode (|||31744|)\r\n");
96 return Verify("EPSV\r\n", data
, PRE_RETR
,
97 "227 Entering Extended Passive Mode (|||31744|)\r\n");
99 return Verify("PASV\r\n", data
, PRE_CWD
,
100 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
102 return Verify("PASV\r\n", data
, PRE_RETR
,
103 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
105 return Verify("PASV\r\n", data
, PRE_SIZE
,
106 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
108 // Use unallocated 599 FTP error code to make sure it falls into the
109 // generic ERR_FTP_FAILED bucket.
110 return Verify("PASV\r\n", data
, PRE_QUIT
,
113 return Verify("QUIT\r\n", data
, QUIT
, "221 Goodbye.\r\n");
115 NOTREACHED() << "State not handled " << state();
116 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
120 void InjectFailure(State state
, State next_state
, const char* response
) {
121 DCHECK_EQ(NONE
, failure_injection_state_
);
122 DCHECK_NE(NONE
, state
);
123 DCHECK_NE(NONE
, next_state
);
124 DCHECK_NE(state
, next_state
);
125 failure_injection_state_
= state
;
126 failure_injection_next_state_
= next_state
;
127 fault_response_
= response
;
130 State
state() const {
134 virtual void Reset() OVERRIDE
{
135 DynamicSocketDataProvider::Reset();
139 void set_multiline_welcome(bool multiline
) { multiline_welcome_
= multiline
; }
141 bool use_epsv() const { return use_epsv_
; }
142 void set_use_epsv(bool use_epsv
) { use_epsv_
= use_epsv
; }
144 void set_data_type(char data_type
) { data_type_
= data_type
; }
149 SimulateRead("220 host TestFTPd\r\n");
152 // If protocol fault injection has been requested, adjusts state and mocked
153 // read and returns true.
155 if (state_
!= failure_injection_state_
)
157 SimulateRead(fault_response_
);
158 state_
= failure_injection_next_state_
;
162 MockWriteResult
Verify(const std::string
& expected
,
163 const std::string
& data
,
165 const char* next_read
,
166 const size_t next_read_length
) {
167 EXPECT_EQ(expected
, data
);
168 if (expected
== data
) {
170 SimulateRead(next_read
, next_read_length
);
171 return MockWriteResult(ASYNC
, data
.length());
173 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
176 MockWriteResult
Verify(const std::string
& expected
,
177 const std::string
& data
,
179 const char* next_read
) {
180 return Verify(expected
, data
, next_state
,
181 next_read
, std::strlen(next_read
));
187 State failure_injection_state_
;
188 State failure_injection_next_state_
;
189 const char* fault_response_
;
191 // If true, we will send multiple 230 lines as response after PASS.
192 bool multiline_welcome_
;
194 // If true, we will use EPSV command.
197 // Data type to be used for TYPE command.
200 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider
);
203 class FtpSocketDataProviderDirectoryListing
: public FtpSocketDataProvider
{
205 FtpSocketDataProviderDirectoryListing() {
208 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
210 return MockWriteResult(ASYNC
, data
.length());
213 return Verify("SIZE /\r\n", data
,
214 use_epsv() ? PRE_CWD_EPSV
: PRE_CWD_PASV
,
215 "550 I can only retrieve regular files\r\n");
217 return Verify("CWD /\r\n", data
, PRE_LIST
, "200 OK\r\n");
219 return Verify("LIST -l\r\n", data
, PRE_QUIT
, "200 OK\r\n");
221 return FtpSocketDataProvider::OnWrite(data
);
226 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing
);
229 class FtpSocketDataProviderDirectoryListingWithPasvFallback
230 : public FtpSocketDataProviderDirectoryListing
{
232 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
235 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
237 return MockWriteResult(ASYNC
, data
.length());
240 return Verify("EPSV\r\n", data
, PRE_PASV
,
241 "500 no EPSV for you\r\n");
243 return Verify("SIZE /\r\n", data
, PRE_CWD_PASV
,
244 "550 I can only retrieve regular files\r\n");
246 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
251 DISALLOW_COPY_AND_ASSIGN(
252 FtpSocketDataProviderDirectoryListingWithPasvFallback
);
255 class FtpSocketDataProviderDirectoryListingZeroSize
256 : public FtpSocketDataProviderDirectoryListing
{
258 FtpSocketDataProviderDirectoryListingZeroSize() {
261 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
263 return MockWriteResult(ASYNC
, data
.length());
266 return Verify("SIZE /\r\n", data
, PRE_CWD
, "213 0\r\n");
268 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
273 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize
);
276 class FtpSocketDataProviderVMSDirectoryListing
: public FtpSocketDataProvider
{
278 FtpSocketDataProviderVMSDirectoryListing() {
281 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
283 return MockWriteResult(ASYNC
, data
.length());
286 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
288 return Verify("PWD\r\n", data
, PRE_TYPE
,
289 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
291 return Verify("EPSV\r\n", data
, PRE_PASV
, "500 Invalid command\r\n");
293 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data
, PRE_CWD_PASV
,
294 "550 I can only retrieve regular files\r\n");
296 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data
, PRE_LIST
,
299 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
301 return FtpSocketDataProvider::OnWrite(data
);
306 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing
);
309 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
310 : public FtpSocketDataProvider
{
312 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
315 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
317 return MockWriteResult(ASYNC
, data
.length());
320 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
322 return Verify("PWD\r\n", data
, PRE_TYPE
,
323 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
325 return Verify("EPSV\r\n", data
, PRE_PASV
,
326 "500 EPSV command unknown\r\n");
328 return Verify("SIZE ANONYMOUS_ROOT\r\n", data
, PRE_CWD_PASV
,
329 "550 I can only retrieve regular files\r\n");
331 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data
, PRE_LIST
,
334 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
336 return FtpSocketDataProvider::OnWrite(data
);
341 DISALLOW_COPY_AND_ASSIGN(
342 FtpSocketDataProviderVMSDirectoryListingRootDirectory
);
345 class FtpSocketDataProviderFileDownloadWithFileTypecode
346 : public FtpSocketDataProvider
{
348 FtpSocketDataProviderFileDownloadWithFileTypecode() {
351 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
353 return MockWriteResult(ASYNC
, data
.length());
356 return Verify("SIZE /file\r\n", data
, PRE_RETR
,
359 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
361 return FtpSocketDataProvider::OnWrite(data
);
366 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode
);
369 class FtpSocketDataProviderFileDownload
: public FtpSocketDataProvider
{
371 FtpSocketDataProviderFileDownload() {
374 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
376 return MockWriteResult(ASYNC
, data
.length());
379 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
382 return Verify("CWD /file\r\n", data
,
383 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
384 "550 Not a directory\r\n");
386 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
388 return FtpSocketDataProvider::OnWrite(data
);
393 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload
);
396 class FtpSocketDataProviderFileNotFound
: public FtpSocketDataProvider
{
398 FtpSocketDataProviderFileNotFound() {
401 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
403 return MockWriteResult(ASYNC
, data
.length());
406 return Verify("SIZE /file\r\n", data
,
407 use_epsv() ? PRE_CWD_EPSV
: PRE_CWD_PASV
,
408 "550 File Not Found\r\n");
410 return Verify("CWD /file\r\n", data
,
411 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
412 "550 File Not Found\r\n");
414 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
415 "550 File Not Found\r\n");
417 return FtpSocketDataProvider::OnWrite(data
);
422 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound
);
425 class FtpSocketDataProviderFileDownloadWithPasvFallback
426 : public FtpSocketDataProviderFileDownload
{
428 FtpSocketDataProviderFileDownloadWithPasvFallback() {
431 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
433 return MockWriteResult(ASYNC
, data
.length());
436 return Verify("EPSV\r\n", data
, PRE_PASV
,
437 "500 No can do\r\n");
439 return Verify("CWD /file\r\n", data
, PRE_RETR_PASV
,
440 "550 Not a directory\r\n");
442 return FtpSocketDataProviderFileDownload::OnWrite(data
);
447 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback
);
450 class FtpSocketDataProviderFileDownloadZeroSize
451 : public FtpSocketDataProviderFileDownload
{
453 FtpSocketDataProviderFileDownloadZeroSize() {
456 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
458 return MockWriteResult(ASYNC
, data
.length());
461 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
464 return Verify("CWD /file\r\n", data
,
465 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
466 "550 not a directory\r\n");
468 return FtpSocketDataProviderFileDownload::OnWrite(data
);
473 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize
);
476 class FtpSocketDataProviderFileDownloadCWD451
477 : public FtpSocketDataProviderFileDownload
{
479 FtpSocketDataProviderFileDownloadCWD451() {
482 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
484 return MockWriteResult(ASYNC
, data
.length());
487 return Verify("CWD /file\r\n", data
,
488 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
489 "451 not a directory\r\n");
491 return FtpSocketDataProviderFileDownload::OnWrite(data
);
496 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451
);
499 class FtpSocketDataProviderVMSFileDownload
: public FtpSocketDataProvider
{
501 FtpSocketDataProviderVMSFileDownload() {
504 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
506 return MockWriteResult(ASYNC
, data
.length());
509 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
511 return Verify("PWD\r\n", data
, PRE_TYPE
,
512 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
514 return Verify("EPSV\r\n", data
, PRE_PASV
,
515 "500 EPSV command unknown\r\n");
517 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_CWD
,
520 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data
, PRE_RETR_PASV
,
521 "550 Not a directory\r\n");
523 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_QUIT
,
526 return FtpSocketDataProvider::OnWrite(data
);
531 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload
);
534 class FtpSocketDataProviderEscaping
: public FtpSocketDataProviderFileDownload
{
536 FtpSocketDataProviderEscaping() {
539 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
541 return MockWriteResult(ASYNC
, data
.length());
544 return Verify("SIZE / !\"#$%y\200\201\r\n", data
, PRE_CWD
,
547 return Verify("CWD / !\"#$%y\200\201\r\n", data
,
548 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
549 "550 Not a directory\r\n");
551 return Verify("RETR / !\"#$%y\200\201\r\n", data
, PRE_QUIT
,
554 return FtpSocketDataProviderFileDownload::OnWrite(data
);
559 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping
);
562 class FtpSocketDataProviderFileDownloadTransferStarting
563 : public FtpSocketDataProviderFileDownload
{
565 FtpSocketDataProviderFileDownloadTransferStarting() {
568 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
570 return MockWriteResult(ASYNC
, data
.length());
573 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
574 "125-Data connection already open.\r\n"
575 "125 Transfer starting.\r\n"
576 "226 Transfer complete.\r\n");
578 return FtpSocketDataProviderFileDownload::OnWrite(data
);
583 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting
);
586 class FtpSocketDataProviderDirectoryListingTransferStarting
587 : public FtpSocketDataProviderDirectoryListing
{
589 FtpSocketDataProviderDirectoryListingTransferStarting() {
592 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
594 return MockWriteResult(ASYNC
, data
.length());
597 return Verify("LIST -l\r\n", data
, PRE_QUIT
,
598 "125-Data connection already open.\r\n"
599 "125 Transfer starting.\r\n"
600 "226 Transfer complete.\r\n");
602 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
607 DISALLOW_COPY_AND_ASSIGN(
608 FtpSocketDataProviderDirectoryListingTransferStarting
);
611 class FtpSocketDataProviderFileDownloadInvalidResponse
612 : public FtpSocketDataProviderFileDownload
{
614 FtpSocketDataProviderFileDownloadInvalidResponse() {
617 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
619 return MockWriteResult(ASYNC
, data
.length());
622 // Use unallocated 599 FTP error code to make sure it falls into the
623 // generic ERR_FTP_FAILED bucket.
624 return Verify("SIZE /file\r\n", data
, PRE_QUIT
,
625 "599 Evil Response\r\n"
626 "599 More Evil\r\n");
628 return FtpSocketDataProviderFileDownload::OnWrite(data
);
633 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse
);
636 class FtpSocketDataProviderEvilEpsv
: public FtpSocketDataProviderFileDownload
{
638 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
639 State expected_state
)
640 : epsv_response_(epsv_response
),
641 epsv_response_length_(std::strlen(epsv_response
)),
642 expected_state_(expected_state
) {}
644 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
645 size_t epsv_response_length
,
646 State expected_state
)
647 : epsv_response_(epsv_response
),
648 epsv_response_length_(epsv_response_length
),
649 expected_state_(expected_state
) {}
651 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
653 return MockWriteResult(ASYNC
, data
.length());
656 return Verify("EPSV\r\n", data
, expected_state_
,
657 epsv_response_
, epsv_response_length_
);
659 return FtpSocketDataProviderFileDownload::OnWrite(data
);
664 const char* epsv_response_
;
665 const size_t epsv_response_length_
;
666 const State expected_state_
;
668 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv
);
671 class FtpSocketDataProviderEvilPasv
672 : public FtpSocketDataProviderFileDownloadWithPasvFallback
{
674 FtpSocketDataProviderEvilPasv(const char* pasv_response
, State expected_state
)
675 : pasv_response_(pasv_response
),
676 expected_state_(expected_state
) {
679 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
681 return MockWriteResult(ASYNC
, data
.length());
684 return Verify("PASV\r\n", data
, expected_state_
, pasv_response_
);
686 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data
);
691 const char* pasv_response_
;
692 const State expected_state_
;
694 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv
);
697 class FtpSocketDataProviderEvilSize
: public FtpSocketDataProviderFileDownload
{
699 FtpSocketDataProviderEvilSize(const char* size_response
, State expected_state
)
700 : size_response_(size_response
),
701 expected_state_(expected_state
) {
704 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
706 return MockWriteResult(ASYNC
, data
.length());
709 return Verify("SIZE /file\r\n", data
, expected_state_
, size_response_
);
711 return FtpSocketDataProviderFileDownload::OnWrite(data
);
716 const char* size_response_
;
717 const State expected_state_
;
719 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize
);
722 class FtpSocketDataProviderEvilLogin
723 : public FtpSocketDataProviderFileDownload
{
725 FtpSocketDataProviderEvilLogin(const char* expected_user
,
726 const char* expected_password
)
727 : expected_user_(expected_user
),
728 expected_password_(expected_password
) {
731 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
733 return MockWriteResult(ASYNC
, data
.length());
736 return Verify(std::string("USER ") + expected_user_
+ "\r\n", data
,
737 PRE_PASSWD
, "331 Password needed\r\n");
739 return Verify(std::string("PASS ") + expected_password_
+ "\r\n", data
,
740 PRE_SYST
, "230 Welcome\r\n");
742 return FtpSocketDataProviderFileDownload::OnWrite(data
);
747 const char* expected_user_
;
748 const char* expected_password_
;
750 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin
);
753 class FtpSocketDataProviderCloseConnection
: public FtpSocketDataProvider
{
755 FtpSocketDataProviderCloseConnection() {
758 virtual MockWriteResult
OnWrite(const std::string
& data
) OVERRIDE
{
760 return MockWriteResult(ASYNC
, data
.length());
763 return Verify("USER anonymous\r\n", data
,
766 return FtpSocketDataProvider::OnWrite(data
);
771 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection
);
774 class FtpNetworkTransactionTest
775 : public PlatformTest
,
776 public ::testing::WithParamInterface
<int> {
778 FtpNetworkTransactionTest()
779 : host_resolver_(new MockHostResolver
),
780 session_(new FtpNetworkSession(host_resolver_
.get())),
781 transaction_(session_
.get(), &mock_socket_factory_
) {
782 scoped_refptr
<RuleBasedHostResolverProc
> rules(
783 new RuleBasedHostResolverProc(NULL
));
784 if (GetFamily() == AF_INET
) {
785 rules
->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
786 } else if (GetFamily() == AF_INET6
) {
787 rules
->AddIPLiteralRule("*", "::1", "::1");
791 host_resolver_
->set_rules(rules
.get());
795 // Accessor to make code refactoring-friendly, e.g. when we change the way
796 // parameters are passed (like more parameters).
801 FtpRequestInfo
GetRequestInfo(const std::string
& url
) {
803 info
.url
= GURL(url
);
807 void ExecuteTransaction(FtpSocketDataProvider
* ctrl_socket
,
810 int expected_result
) {
811 // Expect EPSV usage for non-IPv4 control connections.
812 ctrl_socket
->set_use_epsv((GetFamily() != AF_INET
));
814 mock_socket_factory_
.AddSocketDataProvider(ctrl_socket
);
816 std::string
mock_data("mock-data");
817 MockRead data_reads
[] = {
818 // Usually FTP servers close the data connection after the entire data has
820 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
821 MockRead(mock_data
.c_str()),
824 ScopedVector
<StaticSocketDataProvider
> data_sockets
;
825 data_sockets
.reserve(data_socket
);
826 for (int i
= 0; i
< data_socket
+ 1; i
++) {
827 // We only read from one data socket, other ones are dummy.
828 if (i
== data_socket
) {
829 data_sockets
.push_back(new StaticSocketDataProvider(
830 data_reads
, arraysize(data_reads
), NULL
, 0));
832 data_sockets
.push_back(new StaticSocketDataProvider
);
834 mock_socket_factory_
.AddSocketDataProvider(data_sockets
[i
]);
837 FtpRequestInfo request_info
= GetRequestInfo(request
);
838 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
839 ASSERT_EQ(ERR_IO_PENDING
,
840 transaction_
.Start(&request_info
, callback_
.callback(),
842 EXPECT_NE(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
843 ASSERT_EQ(expected_result
, callback_
.WaitForResult());
844 if (expected_result
== OK
) {
845 scoped_refptr
<IOBuffer
> io_buffer(new IOBuffer(kBufferSize
));
846 memset(io_buffer
->data(), 0, kBufferSize
);
847 ASSERT_EQ(ERR_IO_PENDING
,
848 transaction_
.Read(io_buffer
.get(), kBufferSize
,
849 callback_
.callback()));
850 ASSERT_EQ(static_cast<int>(mock_data
.length()),
851 callback_
.WaitForResult());
852 EXPECT_EQ(mock_data
, std::string(io_buffer
->data(), mock_data
.length()));
854 // Do another Read to detect that the data socket is now closed.
855 int rv
= transaction_
.Read(io_buffer
.get(), kBufferSize
,
856 callback_
.callback());
857 if (rv
== ERR_IO_PENDING
) {
858 EXPECT_EQ(0, callback_
.WaitForResult());
863 EXPECT_EQ(FtpSocketDataProvider::QUIT
, ctrl_socket
->state());
864 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
867 void TransactionFailHelper(FtpSocketDataProvider
* ctrl_socket
,
869 FtpSocketDataProvider::State state
,
870 FtpSocketDataProvider::State next_state
,
871 const char* response
,
872 int expected_result
) {
873 ctrl_socket
->InjectFailure(state
, next_state
, response
);
874 ExecuteTransaction(ctrl_socket
, request
, 1, expected_result
);
877 scoped_ptr
<MockHostResolver
> host_resolver_
;
878 scoped_refptr
<FtpNetworkSession
> session_
;
879 MockClientSocketFactory mock_socket_factory_
;
880 FtpNetworkTransaction transaction_
;
881 TestCompletionCallback callback_
;
884 TEST_P(FtpNetworkTransactionTest
, FailedLookup
) {
885 FtpRequestInfo request_info
= GetRequestInfo("ftp://badhost");
886 scoped_refptr
<RuleBasedHostResolverProc
> rules(
887 new RuleBasedHostResolverProc(NULL
));
888 rules
->AddSimulatedFailure("badhost");
889 host_resolver_
->set_rules(rules
.get());
891 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
892 ASSERT_EQ(ERR_IO_PENDING
,
893 transaction_
.Start(&request_info
, callback_
.callback(),
895 ASSERT_EQ(ERR_NAME_NOT_RESOLVED
, callback_
.WaitForResult());
896 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
899 // Check that when determining the host, the square brackets decorating IPv6
900 // literals in URLs are stripped.
901 TEST_P(FtpNetworkTransactionTest
, StripBracketsFromIPv6Literals
) {
902 // This test only makes sense for IPv6 connections.
903 if (GetFamily() != AF_INET6
)
906 host_resolver_
->rules()->AddSimulatedFailure("[::1]");
908 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
909 // The important part of this test is to make sure that we don't fail with
910 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
912 FtpSocketDataProviderEvilSize
ctrl_socket(
913 "213 99999999999999999999999999999999\r\n",
914 FtpSocketDataProvider::PRE_QUIT
);
915 ExecuteTransaction(&ctrl_socket
, "ftp://[::1]/file", 1, ERR_INVALID_RESPONSE
);
918 TEST_P(FtpNetworkTransactionTest
, DirectoryTransaction
) {
919 FtpSocketDataProviderDirectoryListing ctrl_socket
;
920 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
922 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
923 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
924 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
925 transaction_
.GetResponseInfo()->socket_address
.host());
926 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
929 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithPasvFallback
) {
930 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket
;
931 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
933 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
934 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
937 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithTypecode
) {
938 FtpSocketDataProviderDirectoryListing ctrl_socket
;
939 ExecuteTransaction(&ctrl_socket
, "ftp://host;type=d", 1, OK
);
941 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
942 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
945 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcome
) {
946 FtpSocketDataProviderDirectoryListing ctrl_socket
;
947 ctrl_socket
.set_multiline_welcome(true);
948 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
951 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads2
) {
952 FtpSocketDataProviderDirectoryListing ctrl_socket
;
953 ctrl_socket
.set_short_read_limit(2);
954 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
957 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads5
) {
958 FtpSocketDataProviderDirectoryListing ctrl_socket
;
959 ctrl_socket
.set_short_read_limit(5);
960 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
963 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcomeShort
) {
964 FtpSocketDataProviderDirectoryListing ctrl_socket
;
965 // The client will not consume all three 230 lines. That's good, we want to
966 // test that scenario.
967 ctrl_socket
.allow_unconsumed_reads(true);
968 ctrl_socket
.set_multiline_welcome(true);
969 ctrl_socket
.set_short_read_limit(5);
970 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
973 // Regression test for http://crbug.com/60555.
974 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionZeroSize
) {
975 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket
;
976 ExecuteTransaction(&ctrl_socket
, "ftp://host", 0, OK
);
979 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMS
) {
980 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
981 ExecuteTransaction(&ctrl_socket
, "ftp://host/dir", 1, OK
);
984 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMSRootDirectory
) {
985 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket
;
986 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
989 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionTransferStarting
) {
990 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket
;
991 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, OK
);
994 TEST_P(FtpNetworkTransactionTest
, DownloadTransaction
) {
995 FtpSocketDataProviderFileDownload ctrl_socket
;
996 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
998 // We pass an artificial value of 18 as a response to the SIZE command.
999 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1000 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
1001 transaction_
.GetResponseInfo()->socket_address
.host());
1002 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
1005 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithPasvFallback
) {
1006 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket
;
1007 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1009 // We pass an artificial value of 18 as a response to the SIZE command.
1010 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1013 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeA
) {
1014 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1015 ctrl_socket
.set_data_type('A');
1016 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=a", 0, OK
);
1018 // We pass an artificial value of 18 as a response to the SIZE command.
1019 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1022 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeI
) {
1023 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1024 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=i", 0, OK
);
1026 // We pass an artificial value of 18 as a response to the SIZE command.
1027 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1030 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionMultilineWelcome
) {
1031 FtpSocketDataProviderFileDownload ctrl_socket
;
1032 ctrl_socket
.set_multiline_welcome(true);
1033 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1036 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads2
) {
1037 FtpSocketDataProviderFileDownload ctrl_socket
;
1038 ctrl_socket
.set_short_read_limit(2);
1039 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1042 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads5
) {
1043 FtpSocketDataProviderFileDownload ctrl_socket
;
1044 ctrl_socket
.set_short_read_limit(5);
1045 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1048 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionZeroSize
) {
1049 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket
;
1050 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1053 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionCWD451
) {
1054 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket
;
1055 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1058 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionVMS
) {
1059 FtpSocketDataProviderVMSFileDownload ctrl_socket
;
1060 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1063 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionTransferStarting
) {
1064 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket
;
1065 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1068 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionInvalidResponse
) {
1069 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket
;
1070 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1073 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvReallyBadFormat
) {
1074 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,\r\n",
1075 FtpSocketDataProvider::PRE_QUIT
);
1076 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1079 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort1
) {
1080 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1081 FtpSocketDataProvider::PRE_QUIT
);
1082 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1085 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort2
) {
1086 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1087 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1088 FtpSocketDataProvider::PRE_QUIT
);
1089 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1092 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort3
) {
1093 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1094 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1095 FtpSocketDataProvider::PRE_QUIT
);
1096 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1099 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort4
) {
1100 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1101 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1102 FtpSocketDataProvider::PRE_QUIT
);
1103 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1106 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafeHost
) {
1107 FtpSocketDataProviderEvilPasv
ctrl_socket(
1108 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE
);
1109 ctrl_socket
.set_use_epsv(GetFamily() != AF_INET
);
1110 std::string
mock_data("mock-data");
1111 MockRead data_reads
[] = {
1112 MockRead(mock_data
.c_str()),
1114 StaticSocketDataProvider data_socket1
;
1115 StaticSocketDataProvider
data_socket2(data_reads
, arraysize(data_reads
),
1117 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket
);
1118 mock_socket_factory_
.AddSocketDataProvider(&data_socket1
);
1119 mock_socket_factory_
.AddSocketDataProvider(&data_socket2
);
1120 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1122 // Start the transaction.
1123 ASSERT_EQ(ERR_IO_PENDING
,
1124 transaction_
.Start(&request_info
, callback_
.callback(),
1126 ASSERT_EQ(OK
, callback_
.WaitForResult());
1128 // The transaction fires the callback when we can start reading data. That
1129 // means that the data socket should be open.
1130 MockTCPClientSocket
* data_socket
=
1131 static_cast<MockTCPClientSocket
*>(transaction_
.data_socket_
.get());
1132 ASSERT_TRUE(data_socket
);
1133 ASSERT_TRUE(data_socket
->IsConnected());
1135 // Even if the PASV response specified some other address, we connect
1136 // to the address we used for control connection (which could be 127.0.0.1
1137 // or ::1 depending on whether we use IPv6).
1138 for (AddressList::const_iterator it
= data_socket
->addresses().begin();
1139 it
!= data_socket
->addresses().end(); ++it
) {
1140 EXPECT_NE("10.1.2.3", it
->ToStringWithoutPort());
1144 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat1
) {
1145 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1146 if (GetFamily() == AF_INET
)
1149 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22)\r\n",
1150 FtpSocketDataProvider::PRE_QUIT
);
1151 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1154 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat2
) {
1155 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1156 if (GetFamily() == AF_INET
)
1159 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||\r\n",
1160 FtpSocketDataProvider::PRE_QUIT
);
1161 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1164 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat3
) {
1165 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1166 if (GetFamily() == AF_INET
)
1169 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan\r\n",
1170 FtpSocketDataProvider::PRE_QUIT
);
1171 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1174 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat4
) {
1175 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1176 if (GetFamily() == AF_INET
)
1179 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||||)\r\n",
1180 FtpSocketDataProvider::PRE_QUIT
);
1181 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1184 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat5
) {
1185 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1186 if (GetFamily() == AF_INET
)
1189 const char response
[] = "227 Portscan (\0\0\031773\0)\r\n";
1190 FtpSocketDataProviderEvilEpsv
ctrl_socket(response
, sizeof(response
)-1,
1191 FtpSocketDataProvider::PRE_QUIT
);
1192 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1195 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort1
) {
1196 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1197 if (GetFamily() == AF_INET
)
1200 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22|)\r\n",
1201 FtpSocketDataProvider::PRE_QUIT
);
1202 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1205 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort2
) {
1206 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1207 if (GetFamily() == AF_INET
)
1210 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||258|)\r\n",
1211 FtpSocketDataProvider::PRE_QUIT
);
1212 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1215 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort3
) {
1216 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1217 if (GetFamily() == AF_INET
)
1220 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||772|)\r\n",
1221 FtpSocketDataProvider::PRE_QUIT
);
1222 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1225 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort4
) {
1226 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1227 if (GetFamily() == AF_INET
)
1230 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||2049|)\r\n",
1231 FtpSocketDataProvider::PRE_QUIT
);
1232 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1235 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvWeirdSep
) {
1236 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1237 if (GetFamily() == AF_INET
)
1240 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$31744$)\r\n",
1241 FtpSocketDataProvider::PRE_SIZE
);
1242 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1245 TEST_P(FtpNetworkTransactionTest
,
1246 DownloadTransactionEvilEpsvWeirdSepUnsafePort
) {
1247 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1248 if (GetFamily() == AF_INET
)
1251 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$317$)\r\n",
1252 FtpSocketDataProvider::PRE_QUIT
);
1253 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_UNSAFE_PORT
);
1256 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvIllegalHost
) {
1257 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1258 if (GetFamily() == AF_INET
)
1261 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1262 FtpSocketDataProvider::PRE_QUIT
);
1263 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1266 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadUsername
) {
1267 FtpSocketDataProviderEvilLogin
ctrl_socket("hello%0Aworld", "test");
1268 ExecuteTransaction(&ctrl_socket
, "ftp://hello%0Aworld:test@host/file", 1, OK
);
1271 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadPassword
) {
1272 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello%0Dworld");
1273 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%0Dworld@host/file", 1, OK
);
1276 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInLogin
) {
1277 FtpSocketDataProviderEvilLogin
ctrl_socket("hello world", "test");
1278 ExecuteTransaction(&ctrl_socket
, "ftp://hello%20world:test@host/file", 1, OK
);
1281 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInPassword
) {
1282 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello world");
1283 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%20world@host/file", 1, OK
);
1286 TEST_P(FtpNetworkTransactionTest
, EvilRestartUser
) {
1287 FtpSocketDataProvider ctrl_socket1
;
1288 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1289 FtpSocketDataProvider::PRE_QUIT
,
1290 "530 Login authentication failed\r\n");
1291 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1293 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1295 ASSERT_EQ(ERR_IO_PENDING
,
1296 transaction_
.Start(&request_info
, callback_
.callback(),
1298 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1300 MockRead ctrl_reads
[] = {
1301 MockRead("220 host TestFTPd\r\n"),
1302 MockRead("221 Goodbye!\r\n"),
1303 MockRead(SYNCHRONOUS
, OK
),
1305 MockWrite ctrl_writes
[] = {
1306 MockWrite("QUIT\r\n"),
1308 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1309 ctrl_writes
, arraysize(ctrl_writes
));
1310 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1311 ASSERT_EQ(ERR_IO_PENDING
,
1312 transaction_
.RestartWithAuth(
1314 base::ASCIIToUTF16("foo\nownz0red"),
1315 base::ASCIIToUTF16("innocent")),
1316 callback_
.callback()));
1317 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1320 TEST_P(FtpNetworkTransactionTest
, EvilRestartPassword
) {
1321 FtpSocketDataProvider ctrl_socket1
;
1322 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1323 FtpSocketDataProvider::PRE_QUIT
,
1324 "530 Login authentication failed\r\n");
1325 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1327 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1329 ASSERT_EQ(ERR_IO_PENDING
,
1330 transaction_
.Start(&request_info
, callback_
.callback(),
1332 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1334 MockRead ctrl_reads
[] = {
1335 MockRead("220 host TestFTPd\r\n"),
1336 MockRead("331 User okay, send password\r\n"),
1337 MockRead("221 Goodbye!\r\n"),
1338 MockRead(SYNCHRONOUS
, OK
),
1340 MockWrite ctrl_writes
[] = {
1341 MockWrite("USER innocent\r\n"),
1342 MockWrite("QUIT\r\n"),
1344 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1345 ctrl_writes
, arraysize(ctrl_writes
));
1346 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1347 ASSERT_EQ(ERR_IO_PENDING
,
1348 transaction_
.RestartWithAuth(
1349 AuthCredentials(base::ASCIIToUTF16("innocent"),
1350 base::ASCIIToUTF16("foo\nownz0red")),
1351 callback_
.callback()));
1352 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1355 TEST_P(FtpNetworkTransactionTest
, Escaping
) {
1356 FtpSocketDataProviderEscaping ctrl_socket
;
1357 ExecuteTransaction(&ctrl_socket
, "ftp://host/%20%21%22%23%24%25%79%80%81",
1361 // Test for http://crbug.com/23794.
1362 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilSize
) {
1363 // Try to overflow int64 in the response.
1364 FtpSocketDataProviderEvilSize
ctrl_socket(
1365 "213 99999999999999999999999999999999\r\n",
1366 FtpSocketDataProvider::PRE_QUIT
);
1367 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, ERR_INVALID_RESPONSE
);
1370 // Test for http://crbug.com/36360.
1371 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionBigSize
) {
1372 // Pass a valid, but large file size. The transaction should not fail.
1373 FtpSocketDataProviderEvilSize
ctrl_socket(
1374 "213 3204427776\r\n",
1375 FtpSocketDataProvider::PRE_CWD
);
1376 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 1, OK
);
1377 EXPECT_EQ(3204427776LL,
1378 transaction_
.GetResponseInfo()->expected_content_size
);
1381 // Regression test for http://crbug.com/25023.
1382 TEST_P(FtpNetworkTransactionTest
, CloseConnection
) {
1383 FtpSocketDataProviderCloseConnection ctrl_socket
;
1384 ExecuteTransaction(&ctrl_socket
, "ftp://host", 1, ERR_EMPTY_RESPONSE
);
1387 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailUser
) {
1388 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1389 // Use unallocated 599 FTP error code to make sure it falls into the generic
1390 // ERR_FTP_FAILED bucket.
1391 TransactionFailHelper(&ctrl_socket
,
1393 FtpSocketDataProvider::PRE_USER
,
1394 FtpSocketDataProvider::PRE_QUIT
,
1399 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass
) {
1400 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1401 TransactionFailHelper(&ctrl_socket
,
1403 FtpSocketDataProvider::PRE_PASSWD
,
1404 FtpSocketDataProvider::PRE_QUIT
,
1405 "530 Login authentication failed\r\n",
1409 // Regression test for http://crbug.com/38707.
1410 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass503
) {
1411 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1412 TransactionFailHelper(&ctrl_socket
,
1414 FtpSocketDataProvider::PRE_PASSWD
,
1415 FtpSocketDataProvider::PRE_QUIT
,
1416 "503 Bad sequence of commands\r\n",
1417 ERR_FTP_BAD_COMMAND_SEQUENCE
);
1420 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailSyst
) {
1421 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1422 // Use unallocated 599 FTP error code to make sure it falls into the generic
1423 // ERR_FTP_FAILED bucket.
1424 TransactionFailHelper(&ctrl_socket
,
1426 FtpSocketDataProvider::PRE_SYST
,
1427 FtpSocketDataProvider::PRE_PWD
,
1432 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPwd
) {
1433 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1434 // Use unallocated 599 FTP error code to make sure it falls into the generic
1435 // ERR_FTP_FAILED bucket.
1436 TransactionFailHelper(&ctrl_socket
,
1438 FtpSocketDataProvider::PRE_PWD
,
1439 FtpSocketDataProvider::PRE_QUIT
,
1444 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailType
) {
1445 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1446 // Use unallocated 599 FTP error code to make sure it falls into the generic
1447 // ERR_FTP_FAILED bucket.
1448 TransactionFailHelper(&ctrl_socket
,
1450 FtpSocketDataProvider::PRE_TYPE
,
1451 FtpSocketDataProvider::PRE_QUIT
,
1456 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailEpsv
) {
1457 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1458 if (GetFamily() == AF_INET
)
1461 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1462 // Use unallocated 599 FTP error code to make sure it falls into the generic
1463 // ERR_FTP_FAILED bucket.
1464 TransactionFailHelper(&ctrl_socket
,
1466 FtpSocketDataProvider::PRE_EPSV
,
1467 FtpSocketDataProvider::PRE_NOPASV
,
1472 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailCwd
) {
1473 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1474 // Use unallocated 599 FTP error code to make sure it falls into the generic
1475 // ERR_FTP_FAILED bucket.
1476 TransactionFailHelper(&ctrl_socket
,
1478 FtpSocketDataProvider::PRE_CWD
,
1479 FtpSocketDataProvider::PRE_QUIT
,
1484 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailList
) {
1485 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1486 // Use unallocated 599 FTP error code to make sure it falls into the generic
1487 // ERR_FTP_FAILED bucket.
1488 TransactionFailHelper(&ctrl_socket
,
1490 FtpSocketDataProvider::PRE_LIST
,
1491 FtpSocketDataProvider::PRE_QUIT
,
1496 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailUser
) {
1497 FtpSocketDataProviderFileDownload ctrl_socket
;
1498 // Use unallocated 599 FTP error code to make sure it falls into the generic
1499 // ERR_FTP_FAILED bucket.
1500 TransactionFailHelper(&ctrl_socket
,
1502 FtpSocketDataProvider::PRE_USER
,
1503 FtpSocketDataProvider::PRE_QUIT
,
1508 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPass
) {
1509 FtpSocketDataProviderFileDownload ctrl_socket
;
1510 TransactionFailHelper(&ctrl_socket
,
1512 FtpSocketDataProvider::PRE_PASSWD
,
1513 FtpSocketDataProvider::PRE_QUIT
,
1514 "530 Login authentication failed\r\n",
1518 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailSyst
) {
1519 FtpSocketDataProviderFileDownload ctrl_socket
;
1520 // Use unallocated 599 FTP error code to make sure it falls into the generic
1521 // ERR_FTP_FAILED bucket.
1522 TransactionFailHelper(&ctrl_socket
,
1524 FtpSocketDataProvider::PRE_SYST
,
1525 FtpSocketDataProvider::PRE_PWD
,
1530 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPwd
) {
1531 FtpSocketDataProviderFileDownload ctrl_socket
;
1532 // Use unallocated 599 FTP error code to make sure it falls into the generic
1533 // ERR_FTP_FAILED bucket.
1534 TransactionFailHelper(&ctrl_socket
,
1536 FtpSocketDataProvider::PRE_PWD
,
1537 FtpSocketDataProvider::PRE_QUIT
,
1542 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailType
) {
1543 FtpSocketDataProviderFileDownload ctrl_socket
;
1544 // Use unallocated 599 FTP error code to make sure it falls into the generic
1545 // ERR_FTP_FAILED bucket.
1546 TransactionFailHelper(&ctrl_socket
,
1548 FtpSocketDataProvider::PRE_TYPE
,
1549 FtpSocketDataProvider::PRE_QUIT
,
1554 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailEpsv
) {
1555 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1556 if (GetFamily() == AF_INET
)
1559 FtpSocketDataProviderFileDownload ctrl_socket
;
1560 // Use unallocated 599 FTP error code to make sure it falls into the generic
1561 // ERR_FTP_FAILED bucket.
1562 TransactionFailHelper(&ctrl_socket
,
1564 FtpSocketDataProvider::PRE_EPSV
,
1565 FtpSocketDataProvider::PRE_NOPASV
,
1570 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailRetr
) {
1571 FtpSocketDataProviderFileDownload ctrl_socket
;
1572 // Use unallocated 599 FTP error code to make sure it falls into the generic
1573 // ERR_FTP_FAILED bucket.
1574 TransactionFailHelper(&ctrl_socket
,
1576 FtpSocketDataProvider::PRE_RETR
,
1577 FtpSocketDataProvider::PRE_QUIT
,
1582 TEST_P(FtpNetworkTransactionTest
, FileNotFound
) {
1583 FtpSocketDataProviderFileNotFound ctrl_socket
;
1584 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", 2, ERR_FTP_FAILED
);
1587 // Test for http://crbug.com/38845.
1588 TEST_P(FtpNetworkTransactionTest
, ZeroLengthDirInPWD
) {
1589 FtpSocketDataProviderFileDownload ctrl_socket
;
1590 TransactionFailHelper(&ctrl_socket
,
1592 FtpSocketDataProvider::PRE_PWD
,
1593 FtpSocketDataProvider::PRE_TYPE
,
1598 INSTANTIATE_TEST_CASE_P(FTP
,
1599 FtpNetworkTransactionTest
,
1600 ::testing::Values(AF_INET
, AF_INET6
));