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/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_util.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/dns/mock_host_resolver.h"
18 #include "net/ftp/ftp_request_info.h"
19 #include "net/socket/socket_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
25 // Size we use for IOBuffers used to receive data from the test data socket.
26 const int kBufferSize
= 128;
32 class FtpSocketDataProvider
: public SocketDataProvider
{
54 FtpSocketDataProvider()
55 : short_read_limit_(0),
56 allow_unconsumed_reads_(false),
57 failure_injection_state_(NONE
),
58 multiline_welcome_(false),
64 // SocketDataProvider implementation.
65 MockRead
OnRead() override
{
67 return MockRead(SYNCHRONOUS
, ERR_UNEXPECTED
);
68 MockRead result
= reads_
.front();
69 if (short_read_limit_
== 0 || result
.data_len
<= short_read_limit_
) {
72 result
.data_len
= short_read_limit_
;
73 reads_
.front().data
+= result
.data_len
;
74 reads_
.front().data_len
-= result
.data_len
;
79 MockWriteResult
OnWrite(const std::string
& data
) override
{
81 return MockWriteResult(ASYNC
, data
.length());
84 return Verify("USER anonymous\r\n", data
, PRE_PASSWD
,
85 "331 Password needed\r\n");
88 static const char response_one
[] = "230 Welcome\r\n";
89 static const char response_multi
[] =
90 "230- One\r\n230- Two\r\n230 Three\r\n";
91 return Verify("PASS chrome@example.com\r\n", data
, PRE_SYST
,
92 multiline_welcome_
? response_multi
: response_one
);
95 return Verify("SYST\r\n", data
, PRE_PWD
, "215 UNIX\r\n");
97 return Verify("PWD\r\n", data
, PRE_TYPE
,
98 "257 \"/\" is your current location\r\n");
100 return Verify(std::string("TYPE ") + data_type_
+ "\r\n", data
,
101 PRE_SIZE
, "200 TYPE set successfully\r\n");
103 return Verify("EPSV\r\n", data
, PRE_LIST
,
104 "227 Entering Extended Passive Mode (|||31744|)\r\n");
106 return Verify("PASV\r\n", data
, PRE_LIST
,
107 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
109 return Verify("EPSV\r\n", data
, PRE_RETR
,
110 "227 Entering Extended Passive Mode (|||31744|)\r\n");
112 return Verify("PASV\r\n", data
, PRE_RETR
,
113 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
115 // Use unallocated 599 FTP error code to make sure it falls into the
116 // generic ERR_FTP_FAILED bucket.
117 return Verify("PASV\r\n", data
, PRE_QUIT
,
120 return Verify("QUIT\r\n", data
, QUIT
, "221 Goodbye.\r\n");
122 NOTREACHED() << "State not handled " << state();
123 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
127 void InjectFailure(State state
, State next_state
, const char* response
) {
128 DCHECK_EQ(NONE
, failure_injection_state_
);
129 DCHECK_NE(NONE
, state
);
130 DCHECK_NE(NONE
, next_state
);
131 DCHECK_NE(state
, next_state
);
132 failure_injection_state_
= state
;
133 failure_injection_next_state_
= next_state
;
134 fault_response_
= response
;
137 State
state() const {
141 void Reset() override
{
146 bool AllReadDataConsumed() const override
{ return state_
== QUIT
; }
148 bool AllWriteDataConsumed() const override
{ return state_
== QUIT
; }
150 void set_multiline_welcome(bool multiline
) { multiline_welcome_
= multiline
; }
152 bool use_epsv() const { return use_epsv_
; }
153 void set_use_epsv(bool use_epsv
) { use_epsv_
= use_epsv
; }
155 void set_data_type(char data_type
) { data_type_
= data_type
; }
157 int short_read_limit() const { return short_read_limit_
; }
158 void set_short_read_limit(int limit
) { short_read_limit_
= limit
; }
160 void set_allow_unconsumed_reads(bool allow
) {
161 allow_unconsumed_reads_
= allow
;
167 SimulateRead("220 host TestFTPd\r\n");
170 // If protocol fault injection has been requested, adjusts state and mocked
171 // read and returns true.
173 if (state_
!= failure_injection_state_
)
175 SimulateRead(fault_response_
);
176 state_
= failure_injection_next_state_
;
180 MockWriteResult
Verify(const std::string
& expected
,
181 const std::string
& data
,
183 const char* next_read
,
184 const size_t next_read_length
) {
185 EXPECT_EQ(expected
, data
);
186 if (expected
== data
) {
188 SimulateRead(next_read
, next_read_length
);
189 return MockWriteResult(ASYNC
, data
.length());
191 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
194 MockWriteResult
Verify(const std::string
& expected
,
195 const std::string
& data
,
197 const char* next_read
) {
198 return Verify(expected
, data
, next_state
,
199 next_read
, std::strlen(next_read
));
202 // The next time there is a read from this socket, it will return |data|.
203 // Before calling SimulateRead next time, the previous data must be consumed.
204 void SimulateRead(const char* data
, size_t length
) {
205 if (!allow_unconsumed_reads_
) {
206 EXPECT_TRUE(reads_
.empty()) << "Unconsumed read: " << reads_
.front().data
;
208 reads_
.push_back(MockRead(ASYNC
, data
, length
));
210 void SimulateRead(const char* data
) { SimulateRead(data
, std::strlen(data
)); }
213 // List of reads to be consumed.
214 std::deque
<MockRead
> reads_
;
216 // Max number of bytes we will read at a time. 0 means no limit.
217 int short_read_limit_
;
219 // If true, we'll not require the client to consume all data before we
220 // mock the next read.
221 bool allow_unconsumed_reads_
;
224 State failure_injection_state_
;
225 State failure_injection_next_state_
;
226 const char* fault_response_
;
228 // If true, we will send multiple 230 lines as response after PASS.
229 bool multiline_welcome_
;
231 // If true, we will use EPSV command.
234 // Data type to be used for TYPE command.
237 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider
);
240 class FtpSocketDataProviderDirectoryListing
: public FtpSocketDataProvider
{
242 FtpSocketDataProviderDirectoryListing() {
245 MockWriteResult
OnWrite(const std::string
& data
) override
{
247 return MockWriteResult(ASYNC
, data
.length());
250 return Verify("SIZE /\r\n", data
, PRE_CWD
,
251 "550 I can only retrieve regular files\r\n");
253 return Verify("CWD /\r\n", data
,
254 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
256 return Verify("LIST -l\r\n", data
, PRE_QUIT
, "200 OK\r\n");
258 return FtpSocketDataProvider::OnWrite(data
);
263 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing
);
266 class FtpSocketDataProviderDirectoryListingWithPasvFallback
267 : public FtpSocketDataProviderDirectoryListing
{
269 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
272 MockWriteResult
OnWrite(const std::string
& data
) override
{
274 return MockWriteResult(ASYNC
, data
.length());
277 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
278 "500 no EPSV for you\r\n");
280 return Verify("SIZE /\r\n", data
, PRE_CWD
,
281 "550 I can only retrieve regular files\r\n");
283 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
288 DISALLOW_COPY_AND_ASSIGN(
289 FtpSocketDataProviderDirectoryListingWithPasvFallback
);
292 class FtpSocketDataProviderDirectoryListingZeroSize
293 : public FtpSocketDataProviderDirectoryListing
{
295 FtpSocketDataProviderDirectoryListingZeroSize() {
298 MockWriteResult
OnWrite(const std::string
& data
) override
{
300 return MockWriteResult(ASYNC
, data
.length());
303 return Verify("SIZE /\r\n", data
, PRE_CWD
, "213 0\r\n");
305 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
310 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize
);
313 class FtpSocketDataProviderVMSDirectoryListing
: public FtpSocketDataProvider
{
315 FtpSocketDataProviderVMSDirectoryListing() {
318 MockWriteResult
OnWrite(const std::string
& data
) override
{
320 return MockWriteResult(ASYNC
, data
.length());
323 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
325 return Verify("PWD\r\n", data
, PRE_TYPE
,
326 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
328 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
329 "500 Invalid command\r\n");
331 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data
, PRE_CWD
,
332 "550 I can only retrieve regular files\r\n");
334 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data
,
335 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
337 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
339 return FtpSocketDataProvider::OnWrite(data
);
344 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing
);
347 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
348 : public FtpSocketDataProvider
{
350 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
353 MockWriteResult
OnWrite(const std::string
& data
) override
{
355 return MockWriteResult(ASYNC
, data
.length());
358 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
360 return Verify("PWD\r\n", data
, PRE_TYPE
,
361 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
363 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
364 "500 EPSV command unknown\r\n");
366 return Verify("SIZE ANONYMOUS_ROOT\r\n", data
, PRE_CWD
,
367 "550 I can only retrieve regular files\r\n");
369 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data
,
370 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
372 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
374 return FtpSocketDataProvider::OnWrite(data
);
379 DISALLOW_COPY_AND_ASSIGN(
380 FtpSocketDataProviderVMSDirectoryListingRootDirectory
);
383 class FtpSocketDataProviderFileDownloadWithFileTypecode
384 : public FtpSocketDataProvider
{
386 FtpSocketDataProviderFileDownloadWithFileTypecode() {
389 MockWriteResult
OnWrite(const std::string
& data
) override
{
391 return MockWriteResult(ASYNC
, data
.length());
394 return Verify("SIZE /file\r\n", data
,
395 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
, "213 18\r\n");
397 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
399 return FtpSocketDataProvider::OnWrite(data
);
404 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode
);
407 class FtpSocketDataProviderFileDownload
: public FtpSocketDataProvider
{
409 FtpSocketDataProviderFileDownload() {
412 MockWriteResult
OnWrite(const std::string
& data
) override
{
414 return MockWriteResult(ASYNC
, data
.length());
417 return Verify("SIZE /file\r\n", data
, PRE_CWD
, "213 18\r\n");
419 return Verify("CWD /file\r\n", data
,
420 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
421 "550 Not a directory\r\n");
423 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
425 return FtpSocketDataProvider::OnWrite(data
);
430 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload
);
433 class FtpSocketDataProviderFileNotFound
: public FtpSocketDataProvider
{
435 FtpSocketDataProviderFileNotFound() {
438 MockWriteResult
OnWrite(const std::string
& data
) override
{
440 return MockWriteResult(ASYNC
, data
.length());
443 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
444 "550 File Not Found\r\n");
446 return Verify("CWD /file\r\n", data
,
447 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
448 "550 File Not Found\r\n");
450 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
451 "550 File Not Found\r\n");
453 return FtpSocketDataProvider::OnWrite(data
);
458 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound
);
461 class FtpSocketDataProviderFileDownloadWithPasvFallback
462 : public FtpSocketDataProviderFileDownload
{
464 FtpSocketDataProviderFileDownloadWithPasvFallback() {
467 MockWriteResult
OnWrite(const std::string
& data
) override
{
469 return MockWriteResult(ASYNC
, data
.length());
472 return Verify("EPSV\r\n", data
, PRE_RETR_PASV
, "500 No can do\r\n");
474 return Verify("CWD /file\r\n", data
,
475 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
476 "550 Not a directory\r\n");
478 return FtpSocketDataProviderFileDownload::OnWrite(data
);
483 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback
);
486 class FtpSocketDataProviderFileDownloadZeroSize
487 : public FtpSocketDataProviderFileDownload
{
489 FtpSocketDataProviderFileDownloadZeroSize() {
492 MockWriteResult
OnWrite(const std::string
& data
) override
{
494 return MockWriteResult(ASYNC
, data
.length());
497 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
500 return Verify("CWD /file\r\n", data
,
501 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
502 "550 not a directory\r\n");
504 return FtpSocketDataProviderFileDownload::OnWrite(data
);
509 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize
);
512 class FtpSocketDataProviderFileDownloadCWD451
513 : public FtpSocketDataProviderFileDownload
{
515 FtpSocketDataProviderFileDownloadCWD451() {
518 MockWriteResult
OnWrite(const std::string
& data
) override
{
520 return MockWriteResult(ASYNC
, data
.length());
523 return Verify("CWD /file\r\n", data
,
524 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
525 "451 not a directory\r\n");
527 return FtpSocketDataProviderFileDownload::OnWrite(data
);
532 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451
);
535 class FtpSocketDataProviderVMSFileDownload
: public FtpSocketDataProvider
{
537 FtpSocketDataProviderVMSFileDownload() {
540 MockWriteResult
OnWrite(const std::string
& data
) override
{
542 return MockWriteResult(ASYNC
, data
.length());
545 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
547 return Verify("PWD\r\n", data
, PRE_TYPE
,
548 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
550 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
551 "500 EPSV command unknown\r\n");
553 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_CWD
,
556 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data
,
557 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
558 "550 Not a directory\r\n");
560 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_QUIT
,
563 return FtpSocketDataProvider::OnWrite(data
);
568 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload
);
571 class FtpSocketDataProviderEscaping
: public FtpSocketDataProviderFileDownload
{
573 FtpSocketDataProviderEscaping() {
576 MockWriteResult
OnWrite(const std::string
& data
) override
{
578 return MockWriteResult(ASYNC
, data
.length());
581 return Verify("SIZE / !\"#$%y\200\201\r\n", data
, PRE_CWD
,
584 return Verify("CWD / !\"#$%y\200\201\r\n", data
,
585 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
586 "550 Not a directory\r\n");
588 return Verify("RETR / !\"#$%y\200\201\r\n", data
, PRE_QUIT
,
591 return FtpSocketDataProviderFileDownload::OnWrite(data
);
596 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping
);
599 class FtpSocketDataProviderFileDownloadTransferStarting
600 : public FtpSocketDataProviderFileDownload
{
602 FtpSocketDataProviderFileDownloadTransferStarting() {
605 MockWriteResult
OnWrite(const std::string
& data
) override
{
607 return MockWriteResult(ASYNC
, data
.length());
610 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
611 "125-Data connection already open.\r\n"
612 "125 Transfer starting.\r\n"
613 "226 Transfer complete.\r\n");
615 return FtpSocketDataProviderFileDownload::OnWrite(data
);
620 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting
);
623 class FtpSocketDataProviderDirectoryListingTransferStarting
624 : public FtpSocketDataProviderDirectoryListing
{
626 FtpSocketDataProviderDirectoryListingTransferStarting() {
629 MockWriteResult
OnWrite(const std::string
& data
) override
{
631 return MockWriteResult(ASYNC
, data
.length());
634 return Verify("LIST -l\r\n", data
, PRE_QUIT
,
635 "125-Data connection already open.\r\n"
636 "125 Transfer starting.\r\n"
637 "226 Transfer complete.\r\n");
639 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
644 DISALLOW_COPY_AND_ASSIGN(
645 FtpSocketDataProviderDirectoryListingTransferStarting
);
648 class FtpSocketDataProviderFileDownloadInvalidResponse
649 : public FtpSocketDataProviderFileDownload
{
651 FtpSocketDataProviderFileDownloadInvalidResponse() {
654 MockWriteResult
OnWrite(const std::string
& data
) override
{
656 return MockWriteResult(ASYNC
, data
.length());
659 // Use unallocated 599 FTP error code to make sure it falls into the
660 // generic ERR_FTP_FAILED bucket.
661 return Verify("SIZE /file\r\n", data
, PRE_QUIT
,
662 "599 Evil Response\r\n"
663 "599 More Evil\r\n");
665 return FtpSocketDataProviderFileDownload::OnWrite(data
);
670 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse
);
673 class FtpSocketDataProviderEvilEpsv
: public FtpSocketDataProviderFileDownload
{
675 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
676 State expected_state
)
677 : epsv_response_(epsv_response
),
678 epsv_response_length_(std::strlen(epsv_response
)),
679 expected_state_(expected_state
) {}
681 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
682 size_t epsv_response_length
,
683 State expected_state
)
684 : epsv_response_(epsv_response
),
685 epsv_response_length_(epsv_response_length
),
686 expected_state_(expected_state
) {}
688 MockWriteResult
OnWrite(const std::string
& data
) override
{
690 return MockWriteResult(ASYNC
, data
.length());
693 return Verify("EPSV\r\n", data
, expected_state_
,
694 epsv_response_
, epsv_response_length_
);
696 return FtpSocketDataProviderFileDownload::OnWrite(data
);
701 const char* epsv_response_
;
702 const size_t epsv_response_length_
;
703 const State expected_state_
;
705 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv
);
708 class FtpSocketDataProviderEvilPasv
709 : public FtpSocketDataProviderFileDownloadWithPasvFallback
{
711 FtpSocketDataProviderEvilPasv(const char* pasv_response
, State expected_state
)
712 : pasv_response_(pasv_response
),
713 expected_state_(expected_state
) {
716 MockWriteResult
OnWrite(const std::string
& data
) override
{
718 return MockWriteResult(ASYNC
, data
.length());
721 return Verify("PASV\r\n", data
, expected_state_
, pasv_response_
);
723 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data
);
728 const char* pasv_response_
;
729 const State expected_state_
;
731 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv
);
734 class FtpSocketDataProviderEvilSize
: public FtpSocketDataProviderFileDownload
{
736 FtpSocketDataProviderEvilSize(const char* size_response
, State expected_state
)
737 : size_response_(size_response
),
738 expected_state_(expected_state
) {
741 MockWriteResult
OnWrite(const std::string
& data
) override
{
743 return MockWriteResult(ASYNC
, data
.length());
746 return Verify("SIZE /file\r\n", data
, expected_state_
, size_response_
);
748 return FtpSocketDataProviderFileDownload::OnWrite(data
);
753 const char* size_response_
;
754 const State expected_state_
;
756 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize
);
759 class FtpSocketDataProviderEvilLogin
760 : public FtpSocketDataProviderFileDownload
{
762 FtpSocketDataProviderEvilLogin(const char* expected_user
,
763 const char* expected_password
)
764 : expected_user_(expected_user
),
765 expected_password_(expected_password
) {
768 MockWriteResult
OnWrite(const std::string
& data
) override
{
770 return MockWriteResult(ASYNC
, data
.length());
773 return Verify(std::string("USER ") + expected_user_
+ "\r\n", data
,
774 PRE_PASSWD
, "331 Password needed\r\n");
776 return Verify(std::string("PASS ") + expected_password_
+ "\r\n", data
,
777 PRE_SYST
, "230 Welcome\r\n");
779 return FtpSocketDataProviderFileDownload::OnWrite(data
);
784 const char* expected_user_
;
785 const char* expected_password_
;
787 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin
);
790 class FtpSocketDataProviderCloseConnection
: public FtpSocketDataProvider
{
792 FtpSocketDataProviderCloseConnection() {
795 MockWriteResult
OnWrite(const std::string
& data
) override
{
797 return MockWriteResult(ASYNC
, data
.length());
800 return Verify("USER anonymous\r\n", data
,
803 return FtpSocketDataProvider::OnWrite(data
);
808 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection
);
811 class FtpNetworkTransactionTest
812 : public PlatformTest
,
813 public ::testing::WithParamInterface
<int> {
815 FtpNetworkTransactionTest()
816 : host_resolver_(new MockHostResolver
),
817 transaction_(host_resolver_
.get(), &mock_socket_factory_
) {
818 scoped_refptr
<RuleBasedHostResolverProc
> rules(
819 new RuleBasedHostResolverProc(NULL
));
820 if (GetFamily() == AF_INET
) {
821 rules
->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
822 } else if (GetFamily() == AF_INET6
) {
823 rules
->AddIPLiteralRule("*", "::1", "::1");
827 host_resolver_
->set_rules(rules
.get());
831 // Accessor to make code refactoring-friendly, e.g. when we change the way
832 // parameters are passed (like more parameters).
837 FtpRequestInfo
GetRequestInfo(const std::string
& url
) {
839 info
.url
= GURL(url
);
843 void ExecuteTransaction(FtpSocketDataProvider
* ctrl_socket
,
845 int expected_result
) {
846 // Expect EPSV usage for non-IPv4 control connections.
847 ctrl_socket
->set_use_epsv((GetFamily() != AF_INET
));
849 mock_socket_factory_
.AddSocketDataProvider(ctrl_socket
);
851 std::string
mock_data("mock-data");
852 MockRead data_reads
[] = {
853 // Usually FTP servers close the data connection after the entire data has
855 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
856 MockRead(mock_data
.c_str()),
859 scoped_ptr
<StaticSocketDataProvider
> data_socket(
860 new StaticSocketDataProvider(data_reads
, arraysize(data_reads
), NULL
,
862 mock_socket_factory_
.AddSocketDataProvider(data_socket
.get());
863 FtpRequestInfo request_info
= GetRequestInfo(request
);
864 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
865 ASSERT_EQ(ERR_IO_PENDING
,
866 transaction_
.Start(&request_info
, callback_
.callback(),
868 EXPECT_NE(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
869 ASSERT_EQ(expected_result
, callback_
.WaitForResult());
870 if (expected_result
== OK
) {
871 scoped_refptr
<IOBuffer
> io_buffer(new IOBuffer(kBufferSize
));
872 memset(io_buffer
->data(), 0, kBufferSize
);
873 ASSERT_EQ(ERR_IO_PENDING
,
874 transaction_
.Read(io_buffer
.get(), kBufferSize
,
875 callback_
.callback()));
876 ASSERT_EQ(static_cast<int>(mock_data
.length()),
877 callback_
.WaitForResult());
878 EXPECT_EQ(mock_data
, std::string(io_buffer
->data(), mock_data
.length()));
880 // Do another Read to detect that the data socket is now closed.
881 int rv
= transaction_
.Read(io_buffer
.get(), kBufferSize
,
882 callback_
.callback());
883 if (rv
== ERR_IO_PENDING
) {
884 EXPECT_EQ(0, callback_
.WaitForResult());
889 EXPECT_EQ(FtpSocketDataProvider::QUIT
, ctrl_socket
->state());
890 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
893 void TransactionFailHelper(FtpSocketDataProvider
* ctrl_socket
,
895 FtpSocketDataProvider::State state
,
896 FtpSocketDataProvider::State next_state
,
897 const char* response
,
898 int expected_result
) {
899 ctrl_socket
->InjectFailure(state
, next_state
, response
);
900 ExecuteTransaction(ctrl_socket
, request
, expected_result
);
903 scoped_ptr
<MockHostResolver
> host_resolver_
;
904 MockClientSocketFactory mock_socket_factory_
;
905 FtpNetworkTransaction transaction_
;
906 TestCompletionCallback callback_
;
909 TEST_P(FtpNetworkTransactionTest
, FailedLookup
) {
910 FtpRequestInfo request_info
= GetRequestInfo("ftp://badhost");
911 scoped_refptr
<RuleBasedHostResolverProc
> rules(
912 new RuleBasedHostResolverProc(NULL
));
913 rules
->AddSimulatedFailure("badhost");
914 host_resolver_
->set_rules(rules
.get());
916 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
917 ASSERT_EQ(ERR_IO_PENDING
,
918 transaction_
.Start(&request_info
, callback_
.callback(),
920 ASSERT_EQ(ERR_NAME_NOT_RESOLVED
, callback_
.WaitForResult());
921 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
924 // Check that when determining the host, the square brackets decorating IPv6
925 // literals in URLs are stripped.
926 TEST_P(FtpNetworkTransactionTest
, StripBracketsFromIPv6Literals
) {
927 // This test only makes sense for IPv6 connections.
928 if (GetFamily() != AF_INET6
)
931 host_resolver_
->rules()->AddSimulatedFailure("[::1]");
933 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
934 // The important part of this test is to make sure that we don't fail with
935 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
937 FtpSocketDataProviderEvilSize
ctrl_socket(
938 "213 99999999999999999999999999999999\r\n",
939 FtpSocketDataProvider::PRE_QUIT
);
940 ExecuteTransaction(&ctrl_socket
, "ftp://[::1]/file", ERR_INVALID_RESPONSE
);
943 TEST_P(FtpNetworkTransactionTest
, DirectoryTransaction
) {
944 FtpSocketDataProviderDirectoryListing ctrl_socket
;
945 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
947 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
948 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
949 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
950 transaction_
.GetResponseInfo()->socket_address
.host());
951 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
954 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithPasvFallback
) {
955 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket
;
956 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
958 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
959 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
962 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithTypecode
) {
963 FtpSocketDataProviderDirectoryListing ctrl_socket
;
964 ExecuteTransaction(&ctrl_socket
, "ftp://host/;type=d", OK
);
966 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
967 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
970 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcome
) {
971 FtpSocketDataProviderDirectoryListing ctrl_socket
;
972 ctrl_socket
.set_multiline_welcome(true);
973 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
976 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads2
) {
977 FtpSocketDataProviderDirectoryListing ctrl_socket
;
978 ctrl_socket
.set_short_read_limit(2);
979 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
982 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads5
) {
983 FtpSocketDataProviderDirectoryListing ctrl_socket
;
984 ctrl_socket
.set_short_read_limit(5);
985 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
988 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcomeShort
) {
989 FtpSocketDataProviderDirectoryListing ctrl_socket
;
990 // The client will not consume all three 230 lines. That's good, we want to
991 // test that scenario.
992 ctrl_socket
.set_allow_unconsumed_reads(true);
993 ctrl_socket
.set_multiline_welcome(true);
994 ctrl_socket
.set_short_read_limit(5);
995 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
998 // Regression test for http://crbug.com/60555.
999 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionZeroSize
) {
1000 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket
;
1001 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1004 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMS
) {
1005 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1006 ExecuteTransaction(&ctrl_socket
, "ftp://host/dir", OK
);
1009 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMSRootDirectory
) {
1010 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket
;
1011 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1014 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionTransferStarting
) {
1015 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket
;
1016 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1019 TEST_P(FtpNetworkTransactionTest
, DownloadTransaction
) {
1020 FtpSocketDataProviderFileDownload ctrl_socket
;
1021 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1023 // We pass an artificial value of 18 as a response to the SIZE command.
1024 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1025 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
1026 transaction_
.GetResponseInfo()->socket_address
.host());
1027 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
1030 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithPasvFallback
) {
1031 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket
;
1032 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1034 // We pass an artificial value of 18 as a response to the SIZE command.
1035 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1038 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeA
) {
1039 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1040 ctrl_socket
.set_data_type('A');
1041 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=a", OK
);
1043 // We pass an artificial value of 18 as a response to the SIZE command.
1044 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1047 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeI
) {
1048 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1049 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=i", OK
);
1051 // We pass an artificial value of 18 as a response to the SIZE command.
1052 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1055 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionMultilineWelcome
) {
1056 FtpSocketDataProviderFileDownload ctrl_socket
;
1057 ctrl_socket
.set_multiline_welcome(true);
1058 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1061 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads2
) {
1062 FtpSocketDataProviderFileDownload ctrl_socket
;
1063 ctrl_socket
.set_short_read_limit(2);
1064 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1067 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads5
) {
1068 FtpSocketDataProviderFileDownload ctrl_socket
;
1069 ctrl_socket
.set_short_read_limit(5);
1070 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1073 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionZeroSize
) {
1074 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket
;
1075 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1078 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionCWD451
) {
1079 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket
;
1080 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1083 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionVMS
) {
1084 FtpSocketDataProviderVMSFileDownload ctrl_socket
;
1085 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1088 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionTransferStarting
) {
1089 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket
;
1090 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1093 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionInvalidResponse
) {
1094 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket
;
1095 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1098 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvReallyBadFormat
) {
1099 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,\r\n",
1100 FtpSocketDataProvider::PRE_QUIT
);
1101 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1104 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort1
) {
1105 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1106 FtpSocketDataProvider::PRE_QUIT
);
1107 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1110 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort2
) {
1111 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1112 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1113 FtpSocketDataProvider::PRE_QUIT
);
1114 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1117 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort3
) {
1118 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1119 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1120 FtpSocketDataProvider::PRE_QUIT
);
1121 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1124 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort4
) {
1125 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1126 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1127 FtpSocketDataProvider::PRE_QUIT
);
1128 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1131 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafeHost
) {
1132 FtpSocketDataProviderEvilPasv
ctrl_socket(
1133 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR
);
1134 ctrl_socket
.set_use_epsv(GetFamily() != AF_INET
);
1135 std::string
mock_data("mock-data");
1136 MockRead data_reads
[] = {
1137 MockRead(mock_data
.c_str()),
1139 StaticSocketDataProvider data_socket1
;
1140 StaticSocketDataProvider
data_socket2(data_reads
, arraysize(data_reads
),
1142 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket
);
1143 mock_socket_factory_
.AddSocketDataProvider(&data_socket1
);
1144 mock_socket_factory_
.AddSocketDataProvider(&data_socket2
);
1145 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1147 // Start the transaction.
1148 ASSERT_EQ(ERR_IO_PENDING
,
1149 transaction_
.Start(&request_info
, callback_
.callback(),
1151 ASSERT_EQ(OK
, callback_
.WaitForResult());
1153 // The transaction fires the callback when we can start reading data. That
1154 // means that the data socket should be open.
1155 MockTCPClientSocket
* data_socket
=
1156 static_cast<MockTCPClientSocket
*>(transaction_
.data_socket_
.get());
1157 ASSERT_TRUE(data_socket
);
1158 ASSERT_TRUE(data_socket
->IsConnected());
1160 // Even if the PASV response specified some other address, we connect
1161 // to the address we used for control connection (which could be 127.0.0.1
1162 // or ::1 depending on whether we use IPv6).
1163 for (AddressList::const_iterator it
= data_socket
->addresses().begin();
1164 it
!= data_socket
->addresses().end(); ++it
) {
1165 EXPECT_NE("10.1.2.3", it
->ToStringWithoutPort());
1169 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat1
) {
1170 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1171 if (GetFamily() == AF_INET
)
1174 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22)\r\n",
1175 FtpSocketDataProvider::PRE_QUIT
);
1176 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1179 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat2
) {
1180 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1181 if (GetFamily() == AF_INET
)
1184 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||\r\n",
1185 FtpSocketDataProvider::PRE_QUIT
);
1186 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1189 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat3
) {
1190 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1191 if (GetFamily() == AF_INET
)
1194 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan\r\n",
1195 FtpSocketDataProvider::PRE_QUIT
);
1196 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1199 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat4
) {
1200 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1201 if (GetFamily() == AF_INET
)
1204 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||||)\r\n",
1205 FtpSocketDataProvider::PRE_QUIT
);
1206 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1209 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat5
) {
1210 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1211 if (GetFamily() == AF_INET
)
1214 // Breaking the string in the next line prevents MSVC warning C4125.
1215 const char response
[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1216 FtpSocketDataProviderEvilEpsv
ctrl_socket(response
, sizeof(response
)-1,
1217 FtpSocketDataProvider::PRE_QUIT
);
1218 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1221 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort1
) {
1222 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1223 if (GetFamily() == AF_INET
)
1226 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22|)\r\n",
1227 FtpSocketDataProvider::PRE_QUIT
);
1228 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1231 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort2
) {
1232 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1233 if (GetFamily() == AF_INET
)
1236 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||258|)\r\n",
1237 FtpSocketDataProvider::PRE_QUIT
);
1238 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1241 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort3
) {
1242 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1243 if (GetFamily() == AF_INET
)
1246 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||772|)\r\n",
1247 FtpSocketDataProvider::PRE_QUIT
);
1248 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1251 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort4
) {
1252 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1253 if (GetFamily() == AF_INET
)
1256 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||2049|)\r\n",
1257 FtpSocketDataProvider::PRE_QUIT
);
1258 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1261 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvWeirdSep
) {
1262 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1263 if (GetFamily() == AF_INET
)
1266 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$31744$)\r\n",
1267 FtpSocketDataProvider::PRE_RETR
);
1268 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1271 TEST_P(FtpNetworkTransactionTest
,
1272 DownloadTransactionEvilEpsvWeirdSepUnsafePort
) {
1273 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1274 if (GetFamily() == AF_INET
)
1277 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$317$)\r\n",
1278 FtpSocketDataProvider::PRE_QUIT
);
1279 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1282 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvIllegalHost
) {
1283 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1284 if (GetFamily() == AF_INET
)
1287 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1288 FtpSocketDataProvider::PRE_QUIT
);
1289 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1292 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadUsername
) {
1293 FtpSocketDataProviderEvilLogin
ctrl_socket("hello%0Aworld", "test");
1294 ExecuteTransaction(&ctrl_socket
, "ftp://hello%0Aworld:test@host/file", OK
);
1297 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadPassword
) {
1298 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello%0Dworld");
1299 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%0Dworld@host/file", OK
);
1302 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInLogin
) {
1303 FtpSocketDataProviderEvilLogin
ctrl_socket("hello world", "test");
1304 ExecuteTransaction(&ctrl_socket
, "ftp://hello%20world:test@host/file", OK
);
1307 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInPassword
) {
1308 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello world");
1309 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%20world@host/file", OK
);
1312 TEST_P(FtpNetworkTransactionTest
, EvilRestartUser
) {
1313 FtpSocketDataProvider ctrl_socket1
;
1314 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1315 FtpSocketDataProvider::PRE_QUIT
,
1316 "530 Login authentication failed\r\n");
1317 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1319 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1321 ASSERT_EQ(ERR_IO_PENDING
,
1322 transaction_
.Start(&request_info
, callback_
.callback(),
1324 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1326 MockRead ctrl_reads
[] = {
1327 MockRead("220 host TestFTPd\r\n"),
1328 MockRead("221 Goodbye!\r\n"),
1329 MockRead(SYNCHRONOUS
, OK
),
1331 MockWrite ctrl_writes
[] = {
1332 MockWrite("QUIT\r\n"),
1334 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1335 ctrl_writes
, arraysize(ctrl_writes
));
1336 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1337 ASSERT_EQ(ERR_IO_PENDING
,
1338 transaction_
.RestartWithAuth(
1340 base::ASCIIToUTF16("foo\nownz0red"),
1341 base::ASCIIToUTF16("innocent")),
1342 callback_
.callback()));
1343 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1346 TEST_P(FtpNetworkTransactionTest
, EvilRestartPassword
) {
1347 FtpSocketDataProvider ctrl_socket1
;
1348 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1349 FtpSocketDataProvider::PRE_QUIT
,
1350 "530 Login authentication failed\r\n");
1351 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1353 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1355 ASSERT_EQ(ERR_IO_PENDING
,
1356 transaction_
.Start(&request_info
, callback_
.callback(),
1358 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1360 MockRead ctrl_reads
[] = {
1361 MockRead("220 host TestFTPd\r\n"),
1362 MockRead("331 User okay, send password\r\n"),
1363 MockRead("221 Goodbye!\r\n"),
1364 MockRead(SYNCHRONOUS
, OK
),
1366 MockWrite ctrl_writes
[] = {
1367 MockWrite("USER innocent\r\n"),
1368 MockWrite("QUIT\r\n"),
1370 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1371 ctrl_writes
, arraysize(ctrl_writes
));
1372 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1373 ASSERT_EQ(ERR_IO_PENDING
,
1374 transaction_
.RestartWithAuth(
1375 AuthCredentials(base::ASCIIToUTF16("innocent"),
1376 base::ASCIIToUTF16("foo\nownz0red")),
1377 callback_
.callback()));
1378 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1381 TEST_P(FtpNetworkTransactionTest
, Escaping
) {
1382 FtpSocketDataProviderEscaping ctrl_socket
;
1383 ExecuteTransaction(&ctrl_socket
, "ftp://host/%20%21%22%23%24%25%79%80%81",
1387 // Test for http://crbug.com/23794.
1388 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilSize
) {
1389 // Try to overflow int64 in the response.
1390 FtpSocketDataProviderEvilSize
ctrl_socket(
1391 "213 99999999999999999999999999999999\r\n",
1392 FtpSocketDataProvider::PRE_QUIT
);
1393 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1396 // Test for http://crbug.com/36360.
1397 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionBigSize
) {
1398 // Pass a valid, but large file size. The transaction should not fail.
1399 FtpSocketDataProviderEvilSize
ctrl_socket(
1400 "213 3204427776\r\n",
1401 FtpSocketDataProvider::PRE_CWD
);
1402 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1403 EXPECT_EQ(3204427776LL,
1404 transaction_
.GetResponseInfo()->expected_content_size
);
1407 // Regression test for http://crbug.com/25023.
1408 TEST_P(FtpNetworkTransactionTest
, CloseConnection
) {
1409 FtpSocketDataProviderCloseConnection ctrl_socket
;
1410 ExecuteTransaction(&ctrl_socket
, "ftp://host", ERR_EMPTY_RESPONSE
);
1413 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailUser
) {
1414 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1415 // Use unallocated 599 FTP error code to make sure it falls into the generic
1416 // ERR_FTP_FAILED bucket.
1417 TransactionFailHelper(&ctrl_socket
,
1419 FtpSocketDataProvider::PRE_USER
,
1420 FtpSocketDataProvider::PRE_QUIT
,
1425 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass
) {
1426 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1427 TransactionFailHelper(&ctrl_socket
,
1429 FtpSocketDataProvider::PRE_PASSWD
,
1430 FtpSocketDataProvider::PRE_QUIT
,
1431 "530 Login authentication failed\r\n",
1435 // Regression test for http://crbug.com/38707.
1436 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass503
) {
1437 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1438 TransactionFailHelper(&ctrl_socket
,
1440 FtpSocketDataProvider::PRE_PASSWD
,
1441 FtpSocketDataProvider::PRE_QUIT
,
1442 "503 Bad sequence of commands\r\n",
1443 ERR_FTP_BAD_COMMAND_SEQUENCE
);
1446 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailSyst
) {
1447 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1448 // Use unallocated 599 FTP error code to make sure it falls into the generic
1449 // ERR_FTP_FAILED bucket.
1450 TransactionFailHelper(&ctrl_socket
,
1452 FtpSocketDataProvider::PRE_SYST
,
1453 FtpSocketDataProvider::PRE_PWD
,
1458 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPwd
) {
1459 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1460 // Use unallocated 599 FTP error code to make sure it falls into the generic
1461 // ERR_FTP_FAILED bucket.
1462 TransactionFailHelper(&ctrl_socket
,
1464 FtpSocketDataProvider::PRE_PWD
,
1465 FtpSocketDataProvider::PRE_QUIT
,
1470 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailType
) {
1471 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1472 // Use unallocated 599 FTP error code to make sure it falls into the generic
1473 // ERR_FTP_FAILED bucket.
1474 TransactionFailHelper(&ctrl_socket
,
1476 FtpSocketDataProvider::PRE_TYPE
,
1477 FtpSocketDataProvider::PRE_QUIT
,
1482 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailEpsv
) {
1483 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1484 if (GetFamily() == AF_INET
)
1487 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1488 // Use unallocated 599 FTP error code to make sure it falls into the generic
1489 // ERR_FTP_FAILED bucket.
1490 TransactionFailHelper(
1491 &ctrl_socket
, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV
,
1492 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1495 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailCwd
) {
1496 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1497 // Use unallocated 599 FTP error code to make sure it falls into the generic
1498 // ERR_FTP_FAILED bucket.
1499 TransactionFailHelper(&ctrl_socket
,
1501 FtpSocketDataProvider::PRE_CWD
,
1502 FtpSocketDataProvider::PRE_QUIT
,
1507 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailList
) {
1508 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1509 // Use unallocated 599 FTP error code to make sure it falls into the generic
1510 // ERR_FTP_FAILED bucket.
1511 TransactionFailHelper(&ctrl_socket
,
1513 FtpSocketDataProvider::PRE_LIST
,
1514 FtpSocketDataProvider::PRE_QUIT
,
1519 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailUser
) {
1520 FtpSocketDataProviderFileDownload ctrl_socket
;
1521 // Use unallocated 599 FTP error code to make sure it falls into the generic
1522 // ERR_FTP_FAILED bucket.
1523 TransactionFailHelper(&ctrl_socket
,
1525 FtpSocketDataProvider::PRE_USER
,
1526 FtpSocketDataProvider::PRE_QUIT
,
1531 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPass
) {
1532 FtpSocketDataProviderFileDownload ctrl_socket
;
1533 TransactionFailHelper(&ctrl_socket
,
1535 FtpSocketDataProvider::PRE_PASSWD
,
1536 FtpSocketDataProvider::PRE_QUIT
,
1537 "530 Login authentication failed\r\n",
1541 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailSyst
) {
1542 FtpSocketDataProviderFileDownload ctrl_socket
;
1543 // Use unallocated 599 FTP error code to make sure it falls into the generic
1544 // ERR_FTP_FAILED bucket.
1545 TransactionFailHelper(&ctrl_socket
,
1547 FtpSocketDataProvider::PRE_SYST
,
1548 FtpSocketDataProvider::PRE_PWD
,
1553 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPwd
) {
1554 FtpSocketDataProviderFileDownload ctrl_socket
;
1555 // Use unallocated 599 FTP error code to make sure it falls into the generic
1556 // ERR_FTP_FAILED bucket.
1557 TransactionFailHelper(&ctrl_socket
,
1559 FtpSocketDataProvider::PRE_PWD
,
1560 FtpSocketDataProvider::PRE_QUIT
,
1565 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailType
) {
1566 FtpSocketDataProviderFileDownload ctrl_socket
;
1567 // Use unallocated 599 FTP error code to make sure it falls into the generic
1568 // ERR_FTP_FAILED bucket.
1569 TransactionFailHelper(&ctrl_socket
,
1571 FtpSocketDataProvider::PRE_TYPE
,
1572 FtpSocketDataProvider::PRE_QUIT
,
1577 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailEpsv
) {
1578 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1579 if (GetFamily() == AF_INET
)
1582 FtpSocketDataProviderFileDownload ctrl_socket
;
1583 // Use unallocated 599 FTP error code to make sure it falls into the generic
1584 // ERR_FTP_FAILED bucket.
1585 TransactionFailHelper(
1586 &ctrl_socket
, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV
,
1587 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1590 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailRetr
) {
1591 FtpSocketDataProviderFileDownload ctrl_socket
;
1592 // Use unallocated 599 FTP error code to make sure it falls into the generic
1593 // ERR_FTP_FAILED bucket.
1594 TransactionFailHelper(&ctrl_socket
,
1596 FtpSocketDataProvider::PRE_RETR
,
1597 FtpSocketDataProvider::PRE_QUIT
,
1602 TEST_P(FtpNetworkTransactionTest
, FileNotFound
) {
1603 FtpSocketDataProviderFileNotFound ctrl_socket
;
1604 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_FTP_FAILED
);
1607 // Test for http://crbug.com/38845.
1608 TEST_P(FtpNetworkTransactionTest
, ZeroLengthDirInPWD
) {
1609 FtpSocketDataProviderFileDownload ctrl_socket
;
1610 TransactionFailHelper(&ctrl_socket
,
1612 FtpSocketDataProvider::PRE_PWD
,
1613 FtpSocketDataProvider::PRE_TYPE
,
1618 INSTANTIATE_TEST_CASE_P(FTP
,
1619 FtpNetworkTransactionTest
,
1620 ::testing::Values(AF_INET
, AF_INET6
));