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_request_info.h"
20 #include "net/socket/socket_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/platform_test.h"
26 // Size we use for IOBuffers used to receive data from the test data socket.
27 const int kBufferSize
= 128;
33 class FtpSocketDataProvider
: public SocketDataProvider
{
55 FtpSocketDataProvider()
56 : short_read_limit_(0),
57 allow_unconsumed_reads_(false),
58 failure_injection_state_(NONE
),
59 multiline_welcome_(false),
65 // SocketDataProvider implementation.
66 MockRead
OnRead() override
{
68 return MockRead(SYNCHRONOUS
, ERR_UNEXPECTED
);
69 MockRead result
= reads_
.front();
70 if (short_read_limit_
== 0 || result
.data_len
<= short_read_limit_
) {
73 result
.data_len
= short_read_limit_
;
74 reads_
.front().data
+= result
.data_len
;
75 reads_
.front().data_len
-= result
.data_len
;
80 MockWriteResult
OnWrite(const std::string
& data
) override
{
82 return MockWriteResult(ASYNC
, data
.length());
85 return Verify("USER anonymous\r\n", data
, PRE_PASSWD
,
86 "331 Password needed\r\n");
89 static const char response_one
[] = "230 Welcome\r\n";
90 static const char response_multi
[] =
91 "230- One\r\n230- Two\r\n230 Three\r\n";
92 return Verify("PASS chrome@example.com\r\n", data
, PRE_SYST
,
93 multiline_welcome_
? response_multi
: response_one
);
96 return Verify("SYST\r\n", data
, PRE_PWD
, "215 UNIX\r\n");
98 return Verify("PWD\r\n", data
, PRE_TYPE
,
99 "257 \"/\" is your current location\r\n");
101 return Verify(std::string("TYPE ") + data_type_
+ "\r\n", data
,
102 PRE_SIZE
, "200 TYPE set successfully\r\n");
104 return Verify("EPSV\r\n", data
, PRE_LIST
,
105 "227 Entering Extended Passive Mode (|||31744|)\r\n");
107 return Verify("PASV\r\n", data
, PRE_LIST
,
108 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
110 return Verify("EPSV\r\n", data
, PRE_RETR
,
111 "227 Entering Extended Passive Mode (|||31744|)\r\n");
113 return Verify("PASV\r\n", data
, PRE_RETR
,
114 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
116 // Use unallocated 599 FTP error code to make sure it falls into the
117 // generic ERR_FTP_FAILED bucket.
118 return Verify("PASV\r\n", data
, PRE_QUIT
,
121 return Verify("QUIT\r\n", data
, QUIT
, "221 Goodbye.\r\n");
123 NOTREACHED() << "State not handled " << state();
124 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
128 void InjectFailure(State state
, State next_state
, const char* response
) {
129 DCHECK_EQ(NONE
, failure_injection_state_
);
130 DCHECK_NE(NONE
, state
);
131 DCHECK_NE(NONE
, next_state
);
132 DCHECK_NE(state
, next_state
);
133 failure_injection_state_
= state
;
134 failure_injection_next_state_
= next_state
;
135 fault_response_
= response
;
138 State
state() const {
142 void Reset() override
{
147 bool AllReadDataConsumed() const override
{ return state_
== QUIT
; }
149 bool AllWriteDataConsumed() const override
{ return state_
== QUIT
; }
151 void set_multiline_welcome(bool multiline
) { multiline_welcome_
= multiline
; }
153 bool use_epsv() const { return use_epsv_
; }
154 void set_use_epsv(bool use_epsv
) { use_epsv_
= use_epsv
; }
156 void set_data_type(char data_type
) { data_type_
= data_type
; }
158 int short_read_limit() const { return short_read_limit_
; }
159 void set_short_read_limit(int limit
) { short_read_limit_
= limit
; }
161 void set_allow_unconsumed_reads(bool allow
) {
162 allow_unconsumed_reads_
= allow
;
168 SimulateRead("220 host TestFTPd\r\n");
171 // If protocol fault injection has been requested, adjusts state and mocked
172 // read and returns true.
174 if (state_
!= failure_injection_state_
)
176 SimulateRead(fault_response_
);
177 state_
= failure_injection_next_state_
;
181 MockWriteResult
Verify(const std::string
& expected
,
182 const std::string
& data
,
184 const char* next_read
,
185 const size_t next_read_length
) {
186 EXPECT_EQ(expected
, data
);
187 if (expected
== data
) {
189 SimulateRead(next_read
, next_read_length
);
190 return MockWriteResult(ASYNC
, data
.length());
192 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
195 MockWriteResult
Verify(const std::string
& expected
,
196 const std::string
& data
,
198 const char* next_read
) {
199 return Verify(expected
, data
, next_state
,
200 next_read
, std::strlen(next_read
));
203 // The next time there is a read from this socket, it will return |data|.
204 // Before calling SimulateRead next time, the previous data must be consumed.
205 void SimulateRead(const char* data
, size_t length
) {
206 if (!allow_unconsumed_reads_
) {
207 EXPECT_TRUE(reads_
.empty()) << "Unconsumed read: " << reads_
.front().data
;
209 reads_
.push_back(MockRead(ASYNC
, data
, length
));
211 void SimulateRead(const char* data
) { SimulateRead(data
, std::strlen(data
)); }
214 // List of reads to be consumed.
215 std::deque
<MockRead
> reads_
;
217 // Max number of bytes we will read at a time. 0 means no limit.
218 int short_read_limit_
;
220 // If true, we'll not require the client to consume all data before we
221 // mock the next read.
222 bool allow_unconsumed_reads_
;
225 State failure_injection_state_
;
226 State failure_injection_next_state_
;
227 const char* fault_response_
;
229 // If true, we will send multiple 230 lines as response after PASS.
230 bool multiline_welcome_
;
232 // If true, we will use EPSV command.
235 // Data type to be used for TYPE command.
238 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider
);
241 class FtpSocketDataProviderDirectoryListing
: public FtpSocketDataProvider
{
243 FtpSocketDataProviderDirectoryListing() {
246 MockWriteResult
OnWrite(const std::string
& data
) override
{
248 return MockWriteResult(ASYNC
, data
.length());
251 return Verify("SIZE /\r\n", data
, PRE_CWD
,
252 "550 I can only retrieve regular files\r\n");
254 return Verify("CWD /\r\n", data
,
255 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
257 return Verify("LIST -l\r\n", data
, PRE_QUIT
, "200 OK\r\n");
259 return FtpSocketDataProvider::OnWrite(data
);
264 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing
);
267 class FtpSocketDataProviderDirectoryListingWithPasvFallback
268 : public FtpSocketDataProviderDirectoryListing
{
270 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
273 MockWriteResult
OnWrite(const std::string
& data
) override
{
275 return MockWriteResult(ASYNC
, data
.length());
278 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
279 "500 no EPSV for you\r\n");
281 return Verify("SIZE /\r\n", data
, PRE_CWD
,
282 "550 I can only retrieve regular files\r\n");
284 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
289 DISALLOW_COPY_AND_ASSIGN(
290 FtpSocketDataProviderDirectoryListingWithPasvFallback
);
293 class FtpSocketDataProviderDirectoryListingZeroSize
294 : public FtpSocketDataProviderDirectoryListing
{
296 FtpSocketDataProviderDirectoryListingZeroSize() {
299 MockWriteResult
OnWrite(const std::string
& data
) override
{
301 return MockWriteResult(ASYNC
, data
.length());
304 return Verify("SIZE /\r\n", data
, PRE_CWD
, "213 0\r\n");
306 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
311 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize
);
314 class FtpSocketDataProviderVMSDirectoryListing
: public FtpSocketDataProvider
{
316 FtpSocketDataProviderVMSDirectoryListing() {
319 MockWriteResult
OnWrite(const std::string
& data
) override
{
321 return MockWriteResult(ASYNC
, data
.length());
324 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
326 return Verify("PWD\r\n", data
, PRE_TYPE
,
327 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
329 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
330 "500 Invalid command\r\n");
332 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data
, PRE_CWD
,
333 "550 I can only retrieve regular files\r\n");
335 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data
,
336 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
338 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
340 return FtpSocketDataProvider::OnWrite(data
);
345 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing
);
348 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
349 : public FtpSocketDataProvider
{
351 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
354 MockWriteResult
OnWrite(const std::string
& data
) override
{
356 return MockWriteResult(ASYNC
, data
.length());
359 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
361 return Verify("PWD\r\n", data
, PRE_TYPE
,
362 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
364 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
365 "500 EPSV command unknown\r\n");
367 return Verify("SIZE ANONYMOUS_ROOT\r\n", data
, PRE_CWD
,
368 "550 I can only retrieve regular files\r\n");
370 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data
,
371 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
373 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
375 return FtpSocketDataProvider::OnWrite(data
);
380 DISALLOW_COPY_AND_ASSIGN(
381 FtpSocketDataProviderVMSDirectoryListingRootDirectory
);
384 class FtpSocketDataProviderFileDownloadWithFileTypecode
385 : public FtpSocketDataProvider
{
387 FtpSocketDataProviderFileDownloadWithFileTypecode() {
390 MockWriteResult
OnWrite(const std::string
& data
) override
{
392 return MockWriteResult(ASYNC
, data
.length());
395 return Verify("SIZE /file\r\n", data
,
396 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
, "213 18\r\n");
398 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
400 return FtpSocketDataProvider::OnWrite(data
);
405 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode
);
408 class FtpSocketDataProviderFileDownload
: public FtpSocketDataProvider
{
410 FtpSocketDataProviderFileDownload() {
413 MockWriteResult
OnWrite(const std::string
& data
) override
{
415 return MockWriteResult(ASYNC
, data
.length());
418 return Verify("SIZE /file\r\n", data
, PRE_CWD
, "213 18\r\n");
420 return Verify("CWD /file\r\n", data
,
421 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
422 "550 Not a directory\r\n");
424 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
426 return FtpSocketDataProvider::OnWrite(data
);
431 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload
);
434 class FtpSocketDataProviderFileNotFound
: public FtpSocketDataProvider
{
436 FtpSocketDataProviderFileNotFound() {
439 MockWriteResult
OnWrite(const std::string
& data
) override
{
441 return MockWriteResult(ASYNC
, data
.length());
444 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
445 "550 File Not Found\r\n");
447 return Verify("CWD /file\r\n", data
,
448 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
449 "550 File Not Found\r\n");
451 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
452 "550 File Not Found\r\n");
454 return FtpSocketDataProvider::OnWrite(data
);
459 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound
);
462 class FtpSocketDataProviderFileDownloadWithPasvFallback
463 : public FtpSocketDataProviderFileDownload
{
465 FtpSocketDataProviderFileDownloadWithPasvFallback() {
468 MockWriteResult
OnWrite(const std::string
& data
) override
{
470 return MockWriteResult(ASYNC
, data
.length());
473 return Verify("EPSV\r\n", data
, PRE_RETR_PASV
, "500 No can do\r\n");
475 return Verify("CWD /file\r\n", data
,
476 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
477 "550 Not a directory\r\n");
479 return FtpSocketDataProviderFileDownload::OnWrite(data
);
484 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback
);
487 class FtpSocketDataProviderFileDownloadZeroSize
488 : public FtpSocketDataProviderFileDownload
{
490 FtpSocketDataProviderFileDownloadZeroSize() {
493 MockWriteResult
OnWrite(const std::string
& data
) override
{
495 return MockWriteResult(ASYNC
, data
.length());
498 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
501 return Verify("CWD /file\r\n", data
,
502 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
503 "550 not a directory\r\n");
505 return FtpSocketDataProviderFileDownload::OnWrite(data
);
510 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize
);
513 class FtpSocketDataProviderFileDownloadCWD451
514 : public FtpSocketDataProviderFileDownload
{
516 FtpSocketDataProviderFileDownloadCWD451() {
519 MockWriteResult
OnWrite(const std::string
& data
) override
{
521 return MockWriteResult(ASYNC
, data
.length());
524 return Verify("CWD /file\r\n", data
,
525 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
526 "451 not a directory\r\n");
528 return FtpSocketDataProviderFileDownload::OnWrite(data
);
533 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451
);
536 class FtpSocketDataProviderVMSFileDownload
: public FtpSocketDataProvider
{
538 FtpSocketDataProviderVMSFileDownload() {
541 MockWriteResult
OnWrite(const std::string
& data
) override
{
543 return MockWriteResult(ASYNC
, data
.length());
546 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
548 return Verify("PWD\r\n", data
, PRE_TYPE
,
549 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
551 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
552 "500 EPSV command unknown\r\n");
554 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_CWD
,
557 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data
,
558 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
559 "550 Not a directory\r\n");
561 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_QUIT
,
564 return FtpSocketDataProvider::OnWrite(data
);
569 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload
);
572 class FtpSocketDataProviderEscaping
: public FtpSocketDataProviderFileDownload
{
574 FtpSocketDataProviderEscaping() {
577 MockWriteResult
OnWrite(const std::string
& data
) override
{
579 return MockWriteResult(ASYNC
, data
.length());
582 return Verify("SIZE / !\"#$%y\200\201\r\n", data
, PRE_CWD
,
585 return Verify("CWD / !\"#$%y\200\201\r\n", data
,
586 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
587 "550 Not a directory\r\n");
589 return Verify("RETR / !\"#$%y\200\201\r\n", data
, PRE_QUIT
,
592 return FtpSocketDataProviderFileDownload::OnWrite(data
);
597 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping
);
600 class FtpSocketDataProviderFileDownloadTransferStarting
601 : public FtpSocketDataProviderFileDownload
{
603 FtpSocketDataProviderFileDownloadTransferStarting() {
606 MockWriteResult
OnWrite(const std::string
& data
) override
{
608 return MockWriteResult(ASYNC
, data
.length());
611 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
612 "125-Data connection already open.\r\n"
613 "125 Transfer starting.\r\n"
614 "226 Transfer complete.\r\n");
616 return FtpSocketDataProviderFileDownload::OnWrite(data
);
621 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting
);
624 class FtpSocketDataProviderDirectoryListingTransferStarting
625 : public FtpSocketDataProviderDirectoryListing
{
627 FtpSocketDataProviderDirectoryListingTransferStarting() {
630 MockWriteResult
OnWrite(const std::string
& data
) override
{
632 return MockWriteResult(ASYNC
, data
.length());
635 return Verify("LIST -l\r\n", data
, PRE_QUIT
,
636 "125-Data connection already open.\r\n"
637 "125 Transfer starting.\r\n"
638 "226 Transfer complete.\r\n");
640 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
645 DISALLOW_COPY_AND_ASSIGN(
646 FtpSocketDataProviderDirectoryListingTransferStarting
);
649 class FtpSocketDataProviderFileDownloadInvalidResponse
650 : public FtpSocketDataProviderFileDownload
{
652 FtpSocketDataProviderFileDownloadInvalidResponse() {
655 MockWriteResult
OnWrite(const std::string
& data
) override
{
657 return MockWriteResult(ASYNC
, data
.length());
660 // Use unallocated 599 FTP error code to make sure it falls into the
661 // generic ERR_FTP_FAILED bucket.
662 return Verify("SIZE /file\r\n", data
, PRE_QUIT
,
663 "599 Evil Response\r\n"
664 "599 More Evil\r\n");
666 return FtpSocketDataProviderFileDownload::OnWrite(data
);
671 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse
);
674 class FtpSocketDataProviderEvilEpsv
: public FtpSocketDataProviderFileDownload
{
676 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
677 State expected_state
)
678 : epsv_response_(epsv_response
),
679 epsv_response_length_(std::strlen(epsv_response
)),
680 expected_state_(expected_state
) {}
682 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
683 size_t epsv_response_length
,
684 State expected_state
)
685 : epsv_response_(epsv_response
),
686 epsv_response_length_(epsv_response_length
),
687 expected_state_(expected_state
) {}
689 MockWriteResult
OnWrite(const std::string
& data
) override
{
691 return MockWriteResult(ASYNC
, data
.length());
694 return Verify("EPSV\r\n", data
, expected_state_
,
695 epsv_response_
, epsv_response_length_
);
697 return FtpSocketDataProviderFileDownload::OnWrite(data
);
702 const char* epsv_response_
;
703 const size_t epsv_response_length_
;
704 const State expected_state_
;
706 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv
);
709 class FtpSocketDataProviderEvilPasv
710 : public FtpSocketDataProviderFileDownloadWithPasvFallback
{
712 FtpSocketDataProviderEvilPasv(const char* pasv_response
, State expected_state
)
713 : pasv_response_(pasv_response
),
714 expected_state_(expected_state
) {
717 MockWriteResult
OnWrite(const std::string
& data
) override
{
719 return MockWriteResult(ASYNC
, data
.length());
722 return Verify("PASV\r\n", data
, expected_state_
, pasv_response_
);
724 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data
);
729 const char* pasv_response_
;
730 const State expected_state_
;
732 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv
);
735 class FtpSocketDataProviderEvilSize
: public FtpSocketDataProviderFileDownload
{
737 FtpSocketDataProviderEvilSize(const char* size_response
, State expected_state
)
738 : size_response_(size_response
),
739 expected_state_(expected_state
) {
742 MockWriteResult
OnWrite(const std::string
& data
) override
{
744 return MockWriteResult(ASYNC
, data
.length());
747 return Verify("SIZE /file\r\n", data
, expected_state_
, size_response_
);
749 return FtpSocketDataProviderFileDownload::OnWrite(data
);
754 const char* size_response_
;
755 const State expected_state_
;
757 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize
);
760 class FtpSocketDataProviderEvilLogin
761 : public FtpSocketDataProviderFileDownload
{
763 FtpSocketDataProviderEvilLogin(const char* expected_user
,
764 const char* expected_password
)
765 : expected_user_(expected_user
),
766 expected_password_(expected_password
) {
769 MockWriteResult
OnWrite(const std::string
& data
) override
{
771 return MockWriteResult(ASYNC
, data
.length());
774 return Verify(std::string("USER ") + expected_user_
+ "\r\n", data
,
775 PRE_PASSWD
, "331 Password needed\r\n");
777 return Verify(std::string("PASS ") + expected_password_
+ "\r\n", data
,
778 PRE_SYST
, "230 Welcome\r\n");
780 return FtpSocketDataProviderFileDownload::OnWrite(data
);
785 const char* expected_user_
;
786 const char* expected_password_
;
788 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin
);
791 class FtpSocketDataProviderCloseConnection
: public FtpSocketDataProvider
{
793 FtpSocketDataProviderCloseConnection() {
796 MockWriteResult
OnWrite(const std::string
& data
) override
{
798 return MockWriteResult(ASYNC
, data
.length());
801 return Verify("USER anonymous\r\n", data
,
804 return FtpSocketDataProvider::OnWrite(data
);
809 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection
);
812 class FtpNetworkTransactionTest
813 : public PlatformTest
,
814 public ::testing::WithParamInterface
<int> {
816 FtpNetworkTransactionTest()
817 : host_resolver_(new MockHostResolver
),
818 transaction_(host_resolver_
.get(), &mock_socket_factory_
) {
819 scoped_refptr
<RuleBasedHostResolverProc
> rules(
820 new RuleBasedHostResolverProc(NULL
));
821 if (GetFamily() == AF_INET
) {
822 rules
->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
823 } else if (GetFamily() == AF_INET6
) {
824 rules
->AddIPLiteralRule("*", "::1", "::1");
828 host_resolver_
->set_rules(rules
.get());
832 // Accessor to make code refactoring-friendly, e.g. when we change the way
833 // parameters are passed (like more parameters).
838 FtpRequestInfo
GetRequestInfo(const std::string
& url
) {
840 info
.url
= GURL(url
);
844 void ExecuteTransaction(FtpSocketDataProvider
* ctrl_socket
,
846 int expected_result
) {
847 // Expect EPSV usage for non-IPv4 control connections.
848 ctrl_socket
->set_use_epsv((GetFamily() != AF_INET
));
850 mock_socket_factory_
.AddSocketDataProvider(ctrl_socket
);
852 std::string
mock_data("mock-data");
853 MockRead data_reads
[] = {
854 // Usually FTP servers close the data connection after the entire data has
856 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
857 MockRead(mock_data
.c_str()),
860 scoped_ptr
<StaticSocketDataProvider
> data_socket(
861 new StaticSocketDataProvider(data_reads
, arraysize(data_reads
), NULL
,
863 mock_socket_factory_
.AddSocketDataProvider(data_socket
.get());
864 FtpRequestInfo request_info
= GetRequestInfo(request
);
865 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
866 ASSERT_EQ(ERR_IO_PENDING
,
867 transaction_
.Start(&request_info
, callback_
.callback(),
869 EXPECT_NE(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
870 ASSERT_EQ(expected_result
, callback_
.WaitForResult());
871 if (expected_result
== OK
) {
872 scoped_refptr
<IOBuffer
> io_buffer(new IOBuffer(kBufferSize
));
873 memset(io_buffer
->data(), 0, kBufferSize
);
874 ASSERT_EQ(ERR_IO_PENDING
,
875 transaction_
.Read(io_buffer
.get(), kBufferSize
,
876 callback_
.callback()));
877 ASSERT_EQ(static_cast<int>(mock_data
.length()),
878 callback_
.WaitForResult());
879 EXPECT_EQ(mock_data
, std::string(io_buffer
->data(), mock_data
.length()));
881 // Do another Read to detect that the data socket is now closed.
882 int rv
= transaction_
.Read(io_buffer
.get(), kBufferSize
,
883 callback_
.callback());
884 if (rv
== ERR_IO_PENDING
) {
885 EXPECT_EQ(0, callback_
.WaitForResult());
890 EXPECT_EQ(FtpSocketDataProvider::QUIT
, ctrl_socket
->state());
891 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
894 void TransactionFailHelper(FtpSocketDataProvider
* ctrl_socket
,
896 FtpSocketDataProvider::State state
,
897 FtpSocketDataProvider::State next_state
,
898 const char* response
,
899 int expected_result
) {
900 ctrl_socket
->InjectFailure(state
, next_state
, response
);
901 ExecuteTransaction(ctrl_socket
, request
, expected_result
);
904 scoped_ptr
<MockHostResolver
> host_resolver_
;
905 MockClientSocketFactory mock_socket_factory_
;
906 FtpNetworkTransaction transaction_
;
907 TestCompletionCallback callback_
;
910 TEST_P(FtpNetworkTransactionTest
, FailedLookup
) {
911 FtpRequestInfo request_info
= GetRequestInfo("ftp://badhost");
912 scoped_refptr
<RuleBasedHostResolverProc
> rules(
913 new RuleBasedHostResolverProc(NULL
));
914 rules
->AddSimulatedFailure("badhost");
915 host_resolver_
->set_rules(rules
.get());
917 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
918 ASSERT_EQ(ERR_IO_PENDING
,
919 transaction_
.Start(&request_info
, callback_
.callback(),
921 ASSERT_EQ(ERR_NAME_NOT_RESOLVED
, callback_
.WaitForResult());
922 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
925 // Check that when determining the host, the square brackets decorating IPv6
926 // literals in URLs are stripped.
927 TEST_P(FtpNetworkTransactionTest
, StripBracketsFromIPv6Literals
) {
928 // This test only makes sense for IPv6 connections.
929 if (GetFamily() != AF_INET6
)
932 host_resolver_
->rules()->AddSimulatedFailure("[::1]");
934 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
935 // The important part of this test is to make sure that we don't fail with
936 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
938 FtpSocketDataProviderEvilSize
ctrl_socket(
939 "213 99999999999999999999999999999999\r\n",
940 FtpSocketDataProvider::PRE_QUIT
);
941 ExecuteTransaction(&ctrl_socket
, "ftp://[::1]/file", ERR_INVALID_RESPONSE
);
944 TEST_P(FtpNetworkTransactionTest
, DirectoryTransaction
) {
945 FtpSocketDataProviderDirectoryListing ctrl_socket
;
946 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
948 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
949 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
950 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
951 transaction_
.GetResponseInfo()->socket_address
.host());
952 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
955 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithPasvFallback
) {
956 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket
;
957 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
959 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
960 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
963 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithTypecode
) {
964 FtpSocketDataProviderDirectoryListing ctrl_socket
;
965 ExecuteTransaction(&ctrl_socket
, "ftp://host/;type=d", OK
);
967 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
968 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
971 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcome
) {
972 FtpSocketDataProviderDirectoryListing ctrl_socket
;
973 ctrl_socket
.set_multiline_welcome(true);
974 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
977 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads2
) {
978 FtpSocketDataProviderDirectoryListing ctrl_socket
;
979 ctrl_socket
.set_short_read_limit(2);
980 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
983 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads5
) {
984 FtpSocketDataProviderDirectoryListing ctrl_socket
;
985 ctrl_socket
.set_short_read_limit(5);
986 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
989 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcomeShort
) {
990 FtpSocketDataProviderDirectoryListing ctrl_socket
;
991 // The client will not consume all three 230 lines. That's good, we want to
992 // test that scenario.
993 ctrl_socket
.set_allow_unconsumed_reads(true);
994 ctrl_socket
.set_multiline_welcome(true);
995 ctrl_socket
.set_short_read_limit(5);
996 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
999 // Regression test for http://crbug.com/60555.
1000 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionZeroSize
) {
1001 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket
;
1002 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1005 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMS
) {
1006 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1007 ExecuteTransaction(&ctrl_socket
, "ftp://host/dir", OK
);
1010 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMSRootDirectory
) {
1011 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket
;
1012 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1015 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionTransferStarting
) {
1016 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket
;
1017 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1020 TEST_P(FtpNetworkTransactionTest
, DownloadTransaction
) {
1021 FtpSocketDataProviderFileDownload ctrl_socket
;
1022 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1024 // We pass an artificial value of 18 as a response to the SIZE command.
1025 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1026 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
1027 transaction_
.GetResponseInfo()->socket_address
.host());
1028 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
1031 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithPasvFallback
) {
1032 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket
;
1033 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1035 // We pass an artificial value of 18 as a response to the SIZE command.
1036 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1039 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeA
) {
1040 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1041 ctrl_socket
.set_data_type('A');
1042 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=a", OK
);
1044 // We pass an artificial value of 18 as a response to the SIZE command.
1045 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1048 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeI
) {
1049 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1050 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=i", OK
);
1052 // We pass an artificial value of 18 as a response to the SIZE command.
1053 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1056 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionMultilineWelcome
) {
1057 FtpSocketDataProviderFileDownload ctrl_socket
;
1058 ctrl_socket
.set_multiline_welcome(true);
1059 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1062 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads2
) {
1063 FtpSocketDataProviderFileDownload ctrl_socket
;
1064 ctrl_socket
.set_short_read_limit(2);
1065 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1068 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads5
) {
1069 FtpSocketDataProviderFileDownload ctrl_socket
;
1070 ctrl_socket
.set_short_read_limit(5);
1071 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1074 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionZeroSize
) {
1075 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket
;
1076 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1079 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionCWD451
) {
1080 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket
;
1081 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1084 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionVMS
) {
1085 FtpSocketDataProviderVMSFileDownload ctrl_socket
;
1086 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1089 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionTransferStarting
) {
1090 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket
;
1091 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1094 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionInvalidResponse
) {
1095 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket
;
1096 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1099 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvReallyBadFormat
) {
1100 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,\r\n",
1101 FtpSocketDataProvider::PRE_QUIT
);
1102 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1105 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort1
) {
1106 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1107 FtpSocketDataProvider::PRE_QUIT
);
1108 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1111 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort2
) {
1112 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1113 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1114 FtpSocketDataProvider::PRE_QUIT
);
1115 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1118 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort3
) {
1119 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1120 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1121 FtpSocketDataProvider::PRE_QUIT
);
1122 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1125 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort4
) {
1126 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1127 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1128 FtpSocketDataProvider::PRE_QUIT
);
1129 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1132 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafeHost
) {
1133 FtpSocketDataProviderEvilPasv
ctrl_socket(
1134 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR
);
1135 ctrl_socket
.set_use_epsv(GetFamily() != AF_INET
);
1136 std::string
mock_data("mock-data");
1137 MockRead data_reads
[] = {
1138 MockRead(mock_data
.c_str()),
1140 StaticSocketDataProvider data_socket1
;
1141 StaticSocketDataProvider
data_socket2(data_reads
, arraysize(data_reads
),
1143 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket
);
1144 mock_socket_factory_
.AddSocketDataProvider(&data_socket1
);
1145 mock_socket_factory_
.AddSocketDataProvider(&data_socket2
);
1146 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1148 // Start the transaction.
1149 ASSERT_EQ(ERR_IO_PENDING
,
1150 transaction_
.Start(&request_info
, callback_
.callback(),
1152 ASSERT_EQ(OK
, callback_
.WaitForResult());
1154 // The transaction fires the callback when we can start reading data. That
1155 // means that the data socket should be open.
1156 MockTCPClientSocket
* data_socket
=
1157 static_cast<MockTCPClientSocket
*>(transaction_
.data_socket_
.get());
1158 ASSERT_TRUE(data_socket
);
1159 ASSERT_TRUE(data_socket
->IsConnected());
1161 // Even if the PASV response specified some other address, we connect
1162 // to the address we used for control connection (which could be 127.0.0.1
1163 // or ::1 depending on whether we use IPv6).
1164 for (AddressList::const_iterator it
= data_socket
->addresses().begin();
1165 it
!= data_socket
->addresses().end(); ++it
) {
1166 EXPECT_NE("10.1.2.3", it
->ToStringWithoutPort());
1170 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat1
) {
1171 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1172 if (GetFamily() == AF_INET
)
1175 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22)\r\n",
1176 FtpSocketDataProvider::PRE_QUIT
);
1177 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1180 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat2
) {
1181 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1182 if (GetFamily() == AF_INET
)
1185 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||\r\n",
1186 FtpSocketDataProvider::PRE_QUIT
);
1187 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1190 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat3
) {
1191 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1192 if (GetFamily() == AF_INET
)
1195 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan\r\n",
1196 FtpSocketDataProvider::PRE_QUIT
);
1197 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1200 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat4
) {
1201 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1202 if (GetFamily() == AF_INET
)
1205 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||||)\r\n",
1206 FtpSocketDataProvider::PRE_QUIT
);
1207 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1210 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat5
) {
1211 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1212 if (GetFamily() == AF_INET
)
1215 // Breaking the string in the next line prevents MSVC warning C4125.
1216 const char response
[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1217 FtpSocketDataProviderEvilEpsv
ctrl_socket(response
, sizeof(response
)-1,
1218 FtpSocketDataProvider::PRE_QUIT
);
1219 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1222 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort1
) {
1223 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1224 if (GetFamily() == AF_INET
)
1227 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22|)\r\n",
1228 FtpSocketDataProvider::PRE_QUIT
);
1229 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1232 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort2
) {
1233 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1234 if (GetFamily() == AF_INET
)
1237 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||258|)\r\n",
1238 FtpSocketDataProvider::PRE_QUIT
);
1239 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1242 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort3
) {
1243 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1244 if (GetFamily() == AF_INET
)
1247 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||772|)\r\n",
1248 FtpSocketDataProvider::PRE_QUIT
);
1249 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1252 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort4
) {
1253 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1254 if (GetFamily() == AF_INET
)
1257 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||2049|)\r\n",
1258 FtpSocketDataProvider::PRE_QUIT
);
1259 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1262 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvWeirdSep
) {
1263 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1264 if (GetFamily() == AF_INET
)
1267 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$31744$)\r\n",
1268 FtpSocketDataProvider::PRE_RETR
);
1269 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1272 TEST_P(FtpNetworkTransactionTest
,
1273 DownloadTransactionEvilEpsvWeirdSepUnsafePort
) {
1274 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1275 if (GetFamily() == AF_INET
)
1278 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$317$)\r\n",
1279 FtpSocketDataProvider::PRE_QUIT
);
1280 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1283 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvIllegalHost
) {
1284 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1285 if (GetFamily() == AF_INET
)
1288 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1289 FtpSocketDataProvider::PRE_QUIT
);
1290 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1293 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadUsername
) {
1294 FtpSocketDataProviderEvilLogin
ctrl_socket("hello%0Aworld", "test");
1295 ExecuteTransaction(&ctrl_socket
, "ftp://hello%0Aworld:test@host/file", OK
);
1298 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadPassword
) {
1299 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello%0Dworld");
1300 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%0Dworld@host/file", OK
);
1303 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInLogin
) {
1304 FtpSocketDataProviderEvilLogin
ctrl_socket("hello world", "test");
1305 ExecuteTransaction(&ctrl_socket
, "ftp://hello%20world:test@host/file", OK
);
1308 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInPassword
) {
1309 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello world");
1310 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%20world@host/file", OK
);
1313 TEST_P(FtpNetworkTransactionTest
, EvilRestartUser
) {
1314 FtpSocketDataProvider ctrl_socket1
;
1315 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1316 FtpSocketDataProvider::PRE_QUIT
,
1317 "530 Login authentication failed\r\n");
1318 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1320 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1322 ASSERT_EQ(ERR_IO_PENDING
,
1323 transaction_
.Start(&request_info
, callback_
.callback(),
1325 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1327 MockRead ctrl_reads
[] = {
1328 MockRead("220 host TestFTPd\r\n"),
1329 MockRead("221 Goodbye!\r\n"),
1330 MockRead(SYNCHRONOUS
, OK
),
1332 MockWrite ctrl_writes
[] = {
1333 MockWrite("QUIT\r\n"),
1335 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1336 ctrl_writes
, arraysize(ctrl_writes
));
1337 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1338 ASSERT_EQ(ERR_IO_PENDING
,
1339 transaction_
.RestartWithAuth(
1341 base::ASCIIToUTF16("foo\nownz0red"),
1342 base::ASCIIToUTF16("innocent")),
1343 callback_
.callback()));
1344 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1347 TEST_P(FtpNetworkTransactionTest
, EvilRestartPassword
) {
1348 FtpSocketDataProvider ctrl_socket1
;
1349 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1350 FtpSocketDataProvider::PRE_QUIT
,
1351 "530 Login authentication failed\r\n");
1352 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1354 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1356 ASSERT_EQ(ERR_IO_PENDING
,
1357 transaction_
.Start(&request_info
, callback_
.callback(),
1359 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1361 MockRead ctrl_reads
[] = {
1362 MockRead("220 host TestFTPd\r\n"),
1363 MockRead("331 User okay, send password\r\n"),
1364 MockRead("221 Goodbye!\r\n"),
1365 MockRead(SYNCHRONOUS
, OK
),
1367 MockWrite ctrl_writes
[] = {
1368 MockWrite("USER innocent\r\n"),
1369 MockWrite("QUIT\r\n"),
1371 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1372 ctrl_writes
, arraysize(ctrl_writes
));
1373 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1374 ASSERT_EQ(ERR_IO_PENDING
,
1375 transaction_
.RestartWithAuth(
1376 AuthCredentials(base::ASCIIToUTF16("innocent"),
1377 base::ASCIIToUTF16("foo\nownz0red")),
1378 callback_
.callback()));
1379 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1382 TEST_P(FtpNetworkTransactionTest
, Escaping
) {
1383 FtpSocketDataProviderEscaping ctrl_socket
;
1384 ExecuteTransaction(&ctrl_socket
, "ftp://host/%20%21%22%23%24%25%79%80%81",
1388 // Test for http://crbug.com/23794.
1389 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilSize
) {
1390 // Try to overflow int64 in the response.
1391 FtpSocketDataProviderEvilSize
ctrl_socket(
1392 "213 99999999999999999999999999999999\r\n",
1393 FtpSocketDataProvider::PRE_QUIT
);
1394 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1397 // Test for http://crbug.com/36360.
1398 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionBigSize
) {
1399 // Pass a valid, but large file size. The transaction should not fail.
1400 FtpSocketDataProviderEvilSize
ctrl_socket(
1401 "213 3204427776\r\n",
1402 FtpSocketDataProvider::PRE_CWD
);
1403 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1404 EXPECT_EQ(3204427776LL,
1405 transaction_
.GetResponseInfo()->expected_content_size
);
1408 // Regression test for http://crbug.com/25023.
1409 TEST_P(FtpNetworkTransactionTest
, CloseConnection
) {
1410 FtpSocketDataProviderCloseConnection ctrl_socket
;
1411 ExecuteTransaction(&ctrl_socket
, "ftp://host", ERR_EMPTY_RESPONSE
);
1414 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailUser
) {
1415 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1416 // Use unallocated 599 FTP error code to make sure it falls into the generic
1417 // ERR_FTP_FAILED bucket.
1418 TransactionFailHelper(&ctrl_socket
,
1420 FtpSocketDataProvider::PRE_USER
,
1421 FtpSocketDataProvider::PRE_QUIT
,
1426 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass
) {
1427 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1428 TransactionFailHelper(&ctrl_socket
,
1430 FtpSocketDataProvider::PRE_PASSWD
,
1431 FtpSocketDataProvider::PRE_QUIT
,
1432 "530 Login authentication failed\r\n",
1436 // Regression test for http://crbug.com/38707.
1437 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass503
) {
1438 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1439 TransactionFailHelper(&ctrl_socket
,
1441 FtpSocketDataProvider::PRE_PASSWD
,
1442 FtpSocketDataProvider::PRE_QUIT
,
1443 "503 Bad sequence of commands\r\n",
1444 ERR_FTP_BAD_COMMAND_SEQUENCE
);
1447 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailSyst
) {
1448 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1449 // Use unallocated 599 FTP error code to make sure it falls into the generic
1450 // ERR_FTP_FAILED bucket.
1451 TransactionFailHelper(&ctrl_socket
,
1453 FtpSocketDataProvider::PRE_SYST
,
1454 FtpSocketDataProvider::PRE_PWD
,
1459 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPwd
) {
1460 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1461 // Use unallocated 599 FTP error code to make sure it falls into the generic
1462 // ERR_FTP_FAILED bucket.
1463 TransactionFailHelper(&ctrl_socket
,
1465 FtpSocketDataProvider::PRE_PWD
,
1466 FtpSocketDataProvider::PRE_QUIT
,
1471 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailType
) {
1472 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1473 // Use unallocated 599 FTP error code to make sure it falls into the generic
1474 // ERR_FTP_FAILED bucket.
1475 TransactionFailHelper(&ctrl_socket
,
1477 FtpSocketDataProvider::PRE_TYPE
,
1478 FtpSocketDataProvider::PRE_QUIT
,
1483 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailEpsv
) {
1484 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1485 if (GetFamily() == AF_INET
)
1488 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1489 // Use unallocated 599 FTP error code to make sure it falls into the generic
1490 // ERR_FTP_FAILED bucket.
1491 TransactionFailHelper(
1492 &ctrl_socket
, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV
,
1493 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1496 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailCwd
) {
1497 FtpSocketDataProviderDirectoryListing 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_CWD
,
1503 FtpSocketDataProvider::PRE_QUIT
,
1508 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailList
) {
1509 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1510 // Use unallocated 599 FTP error code to make sure it falls into the generic
1511 // ERR_FTP_FAILED bucket.
1512 TransactionFailHelper(&ctrl_socket
,
1514 FtpSocketDataProvider::PRE_LIST
,
1515 FtpSocketDataProvider::PRE_QUIT
,
1520 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailUser
) {
1521 FtpSocketDataProviderFileDownload ctrl_socket
;
1522 // Use unallocated 599 FTP error code to make sure it falls into the generic
1523 // ERR_FTP_FAILED bucket.
1524 TransactionFailHelper(&ctrl_socket
,
1526 FtpSocketDataProvider::PRE_USER
,
1527 FtpSocketDataProvider::PRE_QUIT
,
1532 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPass
) {
1533 FtpSocketDataProviderFileDownload ctrl_socket
;
1534 TransactionFailHelper(&ctrl_socket
,
1536 FtpSocketDataProvider::PRE_PASSWD
,
1537 FtpSocketDataProvider::PRE_QUIT
,
1538 "530 Login authentication failed\r\n",
1542 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailSyst
) {
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_SYST
,
1549 FtpSocketDataProvider::PRE_PWD
,
1554 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPwd
) {
1555 FtpSocketDataProviderFileDownload ctrl_socket
;
1556 // Use unallocated 599 FTP error code to make sure it falls into the generic
1557 // ERR_FTP_FAILED bucket.
1558 TransactionFailHelper(&ctrl_socket
,
1560 FtpSocketDataProvider::PRE_PWD
,
1561 FtpSocketDataProvider::PRE_QUIT
,
1566 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailType
) {
1567 FtpSocketDataProviderFileDownload ctrl_socket
;
1568 // Use unallocated 599 FTP error code to make sure it falls into the generic
1569 // ERR_FTP_FAILED bucket.
1570 TransactionFailHelper(&ctrl_socket
,
1572 FtpSocketDataProvider::PRE_TYPE
,
1573 FtpSocketDataProvider::PRE_QUIT
,
1578 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailEpsv
) {
1579 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1580 if (GetFamily() == AF_INET
)
1583 FtpSocketDataProviderFileDownload ctrl_socket
;
1584 // Use unallocated 599 FTP error code to make sure it falls into the generic
1585 // ERR_FTP_FAILED bucket.
1586 TransactionFailHelper(
1587 &ctrl_socket
, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV
,
1588 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1591 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailRetr
) {
1592 FtpSocketDataProviderFileDownload ctrl_socket
;
1593 // Use unallocated 599 FTP error code to make sure it falls into the generic
1594 // ERR_FTP_FAILED bucket.
1595 TransactionFailHelper(&ctrl_socket
,
1597 FtpSocketDataProvider::PRE_RETR
,
1598 FtpSocketDataProvider::PRE_QUIT
,
1603 TEST_P(FtpNetworkTransactionTest
, FileNotFound
) {
1604 FtpSocketDataProviderFileNotFound ctrl_socket
;
1605 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_FTP_FAILED
);
1608 // Test for http://crbug.com/38845.
1609 TEST_P(FtpNetworkTransactionTest
, ZeroLengthDirInPWD
) {
1610 FtpSocketDataProviderFileDownload ctrl_socket
;
1611 TransactionFailHelper(&ctrl_socket
,
1613 FtpSocketDataProvider::PRE_PWD
,
1614 FtpSocketDataProvider::PRE_TYPE
,
1619 INSTANTIATE_TEST_CASE_P(FTP
,
1620 FtpNetworkTransactionTest
,
1621 ::testing::Values(AF_INET
, AF_INET6
));