1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/ftp/ftp_network_transaction.h"
7 #include "build/build_config.h"
9 #include "base/compiler_specific.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_util.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/ftp/ftp_network_session.h"
20 #include "net/ftp/ftp_request_info.h"
21 #include "net/socket/socket_test_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/platform_test.h"
27 // Size we use for IOBuffers used to receive data from the test data socket.
28 const int kBufferSize
= 128;
34 class FtpSocketDataProvider
: public SocketDataProvider
{
56 FtpSocketDataProvider()
57 : short_read_limit_(0),
58 allow_unconsumed_reads_(false),
59 failure_injection_state_(NONE
),
60 multiline_welcome_(false),
66 // SocketDataProvider implementation.
67 MockRead
OnRead() override
{
69 return MockRead(SYNCHRONOUS
, ERR_UNEXPECTED
);
70 MockRead result
= reads_
.front();
71 if (short_read_limit_
== 0 || result
.data_len
<= short_read_limit_
) {
74 result
.data_len
= short_read_limit_
;
75 reads_
.front().data
+= result
.data_len
;
76 reads_
.front().data_len
-= result
.data_len
;
81 MockWriteResult
OnWrite(const std::string
& data
) override
{
83 return MockWriteResult(ASYNC
, data
.length());
86 return Verify("USER anonymous\r\n", data
, PRE_PASSWD
,
87 "331 Password needed\r\n");
90 static const char response_one
[] = "230 Welcome\r\n";
91 static const char response_multi
[] =
92 "230- One\r\n230- Two\r\n230 Three\r\n";
93 return Verify("PASS chrome@example.com\r\n", data
, PRE_SYST
,
94 multiline_welcome_
? response_multi
: response_one
);
97 return Verify("SYST\r\n", data
, PRE_PWD
, "215 UNIX\r\n");
99 return Verify("PWD\r\n", data
, PRE_TYPE
,
100 "257 \"/\" is your current location\r\n");
102 return Verify(std::string("TYPE ") + data_type_
+ "\r\n", data
,
103 PRE_SIZE
, "200 TYPE set successfully\r\n");
105 return Verify("EPSV\r\n", data
, PRE_LIST
,
106 "227 Entering Extended Passive Mode (|||31744|)\r\n");
108 return Verify("PASV\r\n", data
, PRE_LIST
,
109 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
111 return Verify("EPSV\r\n", data
, PRE_RETR
,
112 "227 Entering Extended Passive Mode (|||31744|)\r\n");
114 return Verify("PASV\r\n", data
, PRE_RETR
,
115 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
117 // Use unallocated 599 FTP error code to make sure it falls into the
118 // generic ERR_FTP_FAILED bucket.
119 return Verify("PASV\r\n", data
, PRE_QUIT
,
122 return Verify("QUIT\r\n", data
, QUIT
, "221 Goodbye.\r\n");
124 NOTREACHED() << "State not handled " << state();
125 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
129 void InjectFailure(State state
, State next_state
, const char* response
) {
130 DCHECK_EQ(NONE
, failure_injection_state_
);
131 DCHECK_NE(NONE
, state
);
132 DCHECK_NE(NONE
, next_state
);
133 DCHECK_NE(state
, next_state
);
134 failure_injection_state_
= state
;
135 failure_injection_next_state_
= next_state
;
136 fault_response_
= response
;
139 State
state() const {
143 void Reset() override
{
148 bool AllReadDataConsumed() const override
{ return state_
== QUIT
; }
150 bool AllWriteDataConsumed() const override
{ return state_
== QUIT
; }
152 void set_multiline_welcome(bool multiline
) { multiline_welcome_
= multiline
; }
154 bool use_epsv() const { return use_epsv_
; }
155 void set_use_epsv(bool use_epsv
) { use_epsv_
= use_epsv
; }
157 void set_data_type(char data_type
) { data_type_
= data_type
; }
159 int short_read_limit() const { return short_read_limit_
; }
160 void set_short_read_limit(int limit
) { short_read_limit_
= limit
; }
162 void set_allow_unconsumed_reads(bool allow
) {
163 allow_unconsumed_reads_
= allow
;
169 SimulateRead("220 host TestFTPd\r\n");
172 // If protocol fault injection has been requested, adjusts state and mocked
173 // read and returns true.
175 if (state_
!= failure_injection_state_
)
177 SimulateRead(fault_response_
);
178 state_
= failure_injection_next_state_
;
182 MockWriteResult
Verify(const std::string
& expected
,
183 const std::string
& data
,
185 const char* next_read
,
186 const size_t next_read_length
) {
187 EXPECT_EQ(expected
, data
);
188 if (expected
== data
) {
190 SimulateRead(next_read
, next_read_length
);
191 return MockWriteResult(ASYNC
, data
.length());
193 return MockWriteResult(ASYNC
, ERR_UNEXPECTED
);
196 MockWriteResult
Verify(const std::string
& expected
,
197 const std::string
& data
,
199 const char* next_read
) {
200 return Verify(expected
, data
, next_state
,
201 next_read
, std::strlen(next_read
));
204 // The next time there is a read from this socket, it will return |data|.
205 // Before calling SimulateRead next time, the previous data must be consumed.
206 void SimulateRead(const char* data
, size_t length
) {
207 if (!allow_unconsumed_reads_
) {
208 EXPECT_TRUE(reads_
.empty()) << "Unconsumed read: " << reads_
.front().data
;
210 reads_
.push_back(MockRead(ASYNC
, data
, length
));
212 void SimulateRead(const char* data
) { SimulateRead(data
, std::strlen(data
)); }
215 // List of reads to be consumed.
216 std::deque
<MockRead
> reads_
;
218 // Max number of bytes we will read at a time. 0 means no limit.
219 int short_read_limit_
;
221 // If true, we'll not require the client to consume all data before we
222 // mock the next read.
223 bool allow_unconsumed_reads_
;
226 State failure_injection_state_
;
227 State failure_injection_next_state_
;
228 const char* fault_response_
;
230 // If true, we will send multiple 230 lines as response after PASS.
231 bool multiline_welcome_
;
233 // If true, we will use EPSV command.
236 // Data type to be used for TYPE command.
239 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider
);
242 class FtpSocketDataProviderDirectoryListing
: public FtpSocketDataProvider
{
244 FtpSocketDataProviderDirectoryListing() {
247 MockWriteResult
OnWrite(const std::string
& data
) override
{
249 return MockWriteResult(ASYNC
, data
.length());
252 return Verify("SIZE /\r\n", data
, PRE_CWD
,
253 "550 I can only retrieve regular files\r\n");
255 return Verify("CWD /\r\n", data
,
256 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
258 return Verify("LIST -l\r\n", data
, PRE_QUIT
, "200 OK\r\n");
260 return FtpSocketDataProvider::OnWrite(data
);
265 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing
);
268 class FtpSocketDataProviderDirectoryListingWithPasvFallback
269 : public FtpSocketDataProviderDirectoryListing
{
271 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
274 MockWriteResult
OnWrite(const std::string
& data
) override
{
276 return MockWriteResult(ASYNC
, data
.length());
279 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
280 "500 no EPSV for you\r\n");
282 return Verify("SIZE /\r\n", data
, PRE_CWD
,
283 "550 I can only retrieve regular files\r\n");
285 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
290 DISALLOW_COPY_AND_ASSIGN(
291 FtpSocketDataProviderDirectoryListingWithPasvFallback
);
294 class FtpSocketDataProviderDirectoryListingZeroSize
295 : public FtpSocketDataProviderDirectoryListing
{
297 FtpSocketDataProviderDirectoryListingZeroSize() {
300 MockWriteResult
OnWrite(const std::string
& data
) override
{
302 return MockWriteResult(ASYNC
, data
.length());
305 return Verify("SIZE /\r\n", data
, PRE_CWD
, "213 0\r\n");
307 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
312 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize
);
315 class FtpSocketDataProviderVMSDirectoryListing
: public FtpSocketDataProvider
{
317 FtpSocketDataProviderVMSDirectoryListing() {
320 MockWriteResult
OnWrite(const std::string
& data
) override
{
322 return MockWriteResult(ASYNC
, data
.length());
325 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
327 return Verify("PWD\r\n", data
, PRE_TYPE
,
328 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
330 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
331 "500 Invalid command\r\n");
333 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data
, PRE_CWD
,
334 "550 I can only retrieve regular files\r\n");
336 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data
,
337 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
339 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
341 return FtpSocketDataProvider::OnWrite(data
);
346 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing
);
349 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
350 : public FtpSocketDataProvider
{
352 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
355 MockWriteResult
OnWrite(const std::string
& data
) override
{
357 return MockWriteResult(ASYNC
, data
.length());
360 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
362 return Verify("PWD\r\n", data
, PRE_TYPE
,
363 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
365 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
366 "500 EPSV command unknown\r\n");
368 return Verify("SIZE ANONYMOUS_ROOT\r\n", data
, PRE_CWD
,
369 "550 I can only retrieve regular files\r\n");
371 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data
,
372 use_epsv() ? PRE_LIST_EPSV
: PRE_LIST_PASV
, "200 OK\r\n");
374 return Verify("LIST *.*;0\r\n", data
, PRE_QUIT
, "200 OK\r\n");
376 return FtpSocketDataProvider::OnWrite(data
);
381 DISALLOW_COPY_AND_ASSIGN(
382 FtpSocketDataProviderVMSDirectoryListingRootDirectory
);
385 class FtpSocketDataProviderFileDownloadWithFileTypecode
386 : public FtpSocketDataProvider
{
388 FtpSocketDataProviderFileDownloadWithFileTypecode() {
391 MockWriteResult
OnWrite(const std::string
& data
) override
{
393 return MockWriteResult(ASYNC
, data
.length());
396 return Verify("SIZE /file\r\n", data
,
397 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
, "213 18\r\n");
399 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
401 return FtpSocketDataProvider::OnWrite(data
);
406 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode
);
409 class FtpSocketDataProviderFileDownload
: public FtpSocketDataProvider
{
411 FtpSocketDataProviderFileDownload() {
414 MockWriteResult
OnWrite(const std::string
& data
) override
{
416 return MockWriteResult(ASYNC
, data
.length());
419 return Verify("SIZE /file\r\n", data
, PRE_CWD
, "213 18\r\n");
421 return Verify("CWD /file\r\n", data
,
422 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
423 "550 Not a directory\r\n");
425 return Verify("RETR /file\r\n", data
, PRE_QUIT
, "200 OK\r\n");
427 return FtpSocketDataProvider::OnWrite(data
);
432 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload
);
435 class FtpSocketDataProviderFileNotFound
: public FtpSocketDataProvider
{
437 FtpSocketDataProviderFileNotFound() {
440 MockWriteResult
OnWrite(const std::string
& data
) override
{
442 return MockWriteResult(ASYNC
, data
.length());
445 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
446 "550 File Not Found\r\n");
448 return Verify("CWD /file\r\n", data
,
449 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
450 "550 File Not Found\r\n");
452 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
453 "550 File Not Found\r\n");
455 return FtpSocketDataProvider::OnWrite(data
);
460 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound
);
463 class FtpSocketDataProviderFileDownloadWithPasvFallback
464 : public FtpSocketDataProviderFileDownload
{
466 FtpSocketDataProviderFileDownloadWithPasvFallback() {
469 MockWriteResult
OnWrite(const std::string
& data
) override
{
471 return MockWriteResult(ASYNC
, data
.length());
474 return Verify("EPSV\r\n", data
, PRE_RETR_PASV
, "500 No can do\r\n");
476 return Verify("CWD /file\r\n", data
,
477 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
478 "550 Not a directory\r\n");
480 return FtpSocketDataProviderFileDownload::OnWrite(data
);
485 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback
);
488 class FtpSocketDataProviderFileDownloadZeroSize
489 : public FtpSocketDataProviderFileDownload
{
491 FtpSocketDataProviderFileDownloadZeroSize() {
494 MockWriteResult
OnWrite(const std::string
& data
) override
{
496 return MockWriteResult(ASYNC
, data
.length());
499 return Verify("SIZE /file\r\n", data
, PRE_CWD
,
502 return Verify("CWD /file\r\n", data
,
503 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
504 "550 not a directory\r\n");
506 return FtpSocketDataProviderFileDownload::OnWrite(data
);
511 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize
);
514 class FtpSocketDataProviderFileDownloadCWD451
515 : public FtpSocketDataProviderFileDownload
{
517 FtpSocketDataProviderFileDownloadCWD451() {
520 MockWriteResult
OnWrite(const std::string
& data
) override
{
522 return MockWriteResult(ASYNC
, data
.length());
525 return Verify("CWD /file\r\n", data
,
526 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
527 "451 not a directory\r\n");
529 return FtpSocketDataProviderFileDownload::OnWrite(data
);
534 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451
);
537 class FtpSocketDataProviderVMSFileDownload
: public FtpSocketDataProvider
{
539 FtpSocketDataProviderVMSFileDownload() {
542 MockWriteResult
OnWrite(const std::string
& data
) override
{
544 return MockWriteResult(ASYNC
, data
.length());
547 return Verify("SYST\r\n", data
, PRE_PWD
, "215 VMS\r\n");
549 return Verify("PWD\r\n", data
, PRE_TYPE
,
550 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
552 return Verify("EPSV\r\n", data
, PRE_LIST_PASV
,
553 "500 EPSV command unknown\r\n");
555 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_CWD
,
558 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data
,
559 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
560 "550 Not a directory\r\n");
562 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data
, PRE_QUIT
,
565 return FtpSocketDataProvider::OnWrite(data
);
570 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload
);
573 class FtpSocketDataProviderEscaping
: public FtpSocketDataProviderFileDownload
{
575 FtpSocketDataProviderEscaping() {
578 MockWriteResult
OnWrite(const std::string
& data
) override
{
580 return MockWriteResult(ASYNC
, data
.length());
583 return Verify("SIZE / !\"#$%y\200\201\r\n", data
, PRE_CWD
,
586 return Verify("CWD / !\"#$%y\200\201\r\n", data
,
587 use_epsv() ? PRE_RETR_EPSV
: PRE_RETR_PASV
,
588 "550 Not a directory\r\n");
590 return Verify("RETR / !\"#$%y\200\201\r\n", data
, PRE_QUIT
,
593 return FtpSocketDataProviderFileDownload::OnWrite(data
);
598 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping
);
601 class FtpSocketDataProviderFileDownloadTransferStarting
602 : public FtpSocketDataProviderFileDownload
{
604 FtpSocketDataProviderFileDownloadTransferStarting() {
607 MockWriteResult
OnWrite(const std::string
& data
) override
{
609 return MockWriteResult(ASYNC
, data
.length());
612 return Verify("RETR /file\r\n", data
, PRE_QUIT
,
613 "125-Data connection already open.\r\n"
614 "125 Transfer starting.\r\n"
615 "226 Transfer complete.\r\n");
617 return FtpSocketDataProviderFileDownload::OnWrite(data
);
622 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting
);
625 class FtpSocketDataProviderDirectoryListingTransferStarting
626 : public FtpSocketDataProviderDirectoryListing
{
628 FtpSocketDataProviderDirectoryListingTransferStarting() {
631 MockWriteResult
OnWrite(const std::string
& data
) override
{
633 return MockWriteResult(ASYNC
, data
.length());
636 return Verify("LIST -l\r\n", data
, PRE_QUIT
,
637 "125-Data connection already open.\r\n"
638 "125 Transfer starting.\r\n"
639 "226 Transfer complete.\r\n");
641 return FtpSocketDataProviderDirectoryListing::OnWrite(data
);
646 DISALLOW_COPY_AND_ASSIGN(
647 FtpSocketDataProviderDirectoryListingTransferStarting
);
650 class FtpSocketDataProviderFileDownloadInvalidResponse
651 : public FtpSocketDataProviderFileDownload
{
653 FtpSocketDataProviderFileDownloadInvalidResponse() {
656 MockWriteResult
OnWrite(const std::string
& data
) override
{
658 return MockWriteResult(ASYNC
, data
.length());
661 // Use unallocated 599 FTP error code to make sure it falls into the
662 // generic ERR_FTP_FAILED bucket.
663 return Verify("SIZE /file\r\n", data
, PRE_QUIT
,
664 "599 Evil Response\r\n"
665 "599 More Evil\r\n");
667 return FtpSocketDataProviderFileDownload::OnWrite(data
);
672 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse
);
675 class FtpSocketDataProviderEvilEpsv
: public FtpSocketDataProviderFileDownload
{
677 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
678 State expected_state
)
679 : epsv_response_(epsv_response
),
680 epsv_response_length_(std::strlen(epsv_response
)),
681 expected_state_(expected_state
) {}
683 FtpSocketDataProviderEvilEpsv(const char* epsv_response
,
684 size_t epsv_response_length
,
685 State expected_state
)
686 : epsv_response_(epsv_response
),
687 epsv_response_length_(epsv_response_length
),
688 expected_state_(expected_state
) {}
690 MockWriteResult
OnWrite(const std::string
& data
) override
{
692 return MockWriteResult(ASYNC
, data
.length());
695 return Verify("EPSV\r\n", data
, expected_state_
,
696 epsv_response_
, epsv_response_length_
);
698 return FtpSocketDataProviderFileDownload::OnWrite(data
);
703 const char* epsv_response_
;
704 const size_t epsv_response_length_
;
705 const State expected_state_
;
707 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv
);
710 class FtpSocketDataProviderEvilPasv
711 : public FtpSocketDataProviderFileDownloadWithPasvFallback
{
713 FtpSocketDataProviderEvilPasv(const char* pasv_response
, State expected_state
)
714 : pasv_response_(pasv_response
),
715 expected_state_(expected_state
) {
718 MockWriteResult
OnWrite(const std::string
& data
) override
{
720 return MockWriteResult(ASYNC
, data
.length());
723 return Verify("PASV\r\n", data
, expected_state_
, pasv_response_
);
725 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data
);
730 const char* pasv_response_
;
731 const State expected_state_
;
733 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv
);
736 class FtpSocketDataProviderEvilSize
: public FtpSocketDataProviderFileDownload
{
738 FtpSocketDataProviderEvilSize(const char* size_response
, State expected_state
)
739 : size_response_(size_response
),
740 expected_state_(expected_state
) {
743 MockWriteResult
OnWrite(const std::string
& data
) override
{
745 return MockWriteResult(ASYNC
, data
.length());
748 return Verify("SIZE /file\r\n", data
, expected_state_
, size_response_
);
750 return FtpSocketDataProviderFileDownload::OnWrite(data
);
755 const char* size_response_
;
756 const State expected_state_
;
758 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize
);
761 class FtpSocketDataProviderEvilLogin
762 : public FtpSocketDataProviderFileDownload
{
764 FtpSocketDataProviderEvilLogin(const char* expected_user
,
765 const char* expected_password
)
766 : expected_user_(expected_user
),
767 expected_password_(expected_password
) {
770 MockWriteResult
OnWrite(const std::string
& data
) override
{
772 return MockWriteResult(ASYNC
, data
.length());
775 return Verify(std::string("USER ") + expected_user_
+ "\r\n", data
,
776 PRE_PASSWD
, "331 Password needed\r\n");
778 return Verify(std::string("PASS ") + expected_password_
+ "\r\n", data
,
779 PRE_SYST
, "230 Welcome\r\n");
781 return FtpSocketDataProviderFileDownload::OnWrite(data
);
786 const char* expected_user_
;
787 const char* expected_password_
;
789 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin
);
792 class FtpSocketDataProviderCloseConnection
: public FtpSocketDataProvider
{
794 FtpSocketDataProviderCloseConnection() {
797 MockWriteResult
OnWrite(const std::string
& data
) override
{
799 return MockWriteResult(ASYNC
, data
.length());
802 return Verify("USER anonymous\r\n", data
,
805 return FtpSocketDataProvider::OnWrite(data
);
810 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection
);
813 class FtpNetworkTransactionTest
814 : public PlatformTest
,
815 public ::testing::WithParamInterface
<int> {
817 FtpNetworkTransactionTest()
818 : host_resolver_(new MockHostResolver
),
819 session_(new FtpNetworkSession(host_resolver_
.get())),
820 transaction_(session_
.get(), &mock_socket_factory_
) {
821 scoped_refptr
<RuleBasedHostResolverProc
> rules(
822 new RuleBasedHostResolverProc(NULL
));
823 if (GetFamily() == AF_INET
) {
824 rules
->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
825 } else if (GetFamily() == AF_INET6
) {
826 rules
->AddIPLiteralRule("*", "::1", "::1");
830 host_resolver_
->set_rules(rules
.get());
834 // Accessor to make code refactoring-friendly, e.g. when we change the way
835 // parameters are passed (like more parameters).
840 FtpRequestInfo
GetRequestInfo(const std::string
& url
) {
842 info
.url
= GURL(url
);
846 void ExecuteTransaction(FtpSocketDataProvider
* ctrl_socket
,
848 int expected_result
) {
849 // Expect EPSV usage for non-IPv4 control connections.
850 ctrl_socket
->set_use_epsv((GetFamily() != AF_INET
));
852 mock_socket_factory_
.AddSocketDataProvider(ctrl_socket
);
854 std::string
mock_data("mock-data");
855 MockRead data_reads
[] = {
856 // Usually FTP servers close the data connection after the entire data has
858 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
859 MockRead(mock_data
.c_str()),
862 scoped_ptr
<StaticSocketDataProvider
> data_socket(
863 new StaticSocketDataProvider(data_reads
, arraysize(data_reads
), NULL
,
865 mock_socket_factory_
.AddSocketDataProvider(data_socket
.get());
866 FtpRequestInfo request_info
= GetRequestInfo(request
);
867 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
868 ASSERT_EQ(ERR_IO_PENDING
,
869 transaction_
.Start(&request_info
, callback_
.callback(),
871 EXPECT_NE(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
872 ASSERT_EQ(expected_result
, callback_
.WaitForResult());
873 if (expected_result
== OK
) {
874 scoped_refptr
<IOBuffer
> io_buffer(new IOBuffer(kBufferSize
));
875 memset(io_buffer
->data(), 0, kBufferSize
);
876 ASSERT_EQ(ERR_IO_PENDING
,
877 transaction_
.Read(io_buffer
.get(), kBufferSize
,
878 callback_
.callback()));
879 ASSERT_EQ(static_cast<int>(mock_data
.length()),
880 callback_
.WaitForResult());
881 EXPECT_EQ(mock_data
, std::string(io_buffer
->data(), mock_data
.length()));
883 // Do another Read to detect that the data socket is now closed.
884 int rv
= transaction_
.Read(io_buffer
.get(), kBufferSize
,
885 callback_
.callback());
886 if (rv
== ERR_IO_PENDING
) {
887 EXPECT_EQ(0, callback_
.WaitForResult());
892 EXPECT_EQ(FtpSocketDataProvider::QUIT
, ctrl_socket
->state());
893 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
896 void TransactionFailHelper(FtpSocketDataProvider
* ctrl_socket
,
898 FtpSocketDataProvider::State state
,
899 FtpSocketDataProvider::State next_state
,
900 const char* response
,
901 int expected_result
) {
902 ctrl_socket
->InjectFailure(state
, next_state
, response
);
903 ExecuteTransaction(ctrl_socket
, request
, expected_result
);
906 scoped_ptr
<MockHostResolver
> host_resolver_
;
907 scoped_refptr
<FtpNetworkSession
> session_
;
908 MockClientSocketFactory mock_socket_factory_
;
909 FtpNetworkTransaction transaction_
;
910 TestCompletionCallback callback_
;
913 TEST_P(FtpNetworkTransactionTest
, FailedLookup
) {
914 FtpRequestInfo request_info
= GetRequestInfo("ftp://badhost");
915 scoped_refptr
<RuleBasedHostResolverProc
> rules(
916 new RuleBasedHostResolverProc(NULL
));
917 rules
->AddSimulatedFailure("badhost");
918 host_resolver_
->set_rules(rules
.get());
920 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
921 ASSERT_EQ(ERR_IO_PENDING
,
922 transaction_
.Start(&request_info
, callback_
.callback(),
924 ASSERT_EQ(ERR_NAME_NOT_RESOLVED
, callback_
.WaitForResult());
925 EXPECT_EQ(LOAD_STATE_IDLE
, transaction_
.GetLoadState());
928 // Check that when determining the host, the square brackets decorating IPv6
929 // literals in URLs are stripped.
930 TEST_P(FtpNetworkTransactionTest
, StripBracketsFromIPv6Literals
) {
931 // This test only makes sense for IPv6 connections.
932 if (GetFamily() != AF_INET6
)
935 host_resolver_
->rules()->AddSimulatedFailure("[::1]");
937 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
938 // The important part of this test is to make sure that we don't fail with
939 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
941 FtpSocketDataProviderEvilSize
ctrl_socket(
942 "213 99999999999999999999999999999999\r\n",
943 FtpSocketDataProvider::PRE_QUIT
);
944 ExecuteTransaction(&ctrl_socket
, "ftp://[::1]/file", ERR_INVALID_RESPONSE
);
947 TEST_P(FtpNetworkTransactionTest
, DirectoryTransaction
) {
948 FtpSocketDataProviderDirectoryListing ctrl_socket
;
949 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
951 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
952 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
953 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
954 transaction_
.GetResponseInfo()->socket_address
.host());
955 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
958 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithPasvFallback
) {
959 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket
;
960 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
962 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
963 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
966 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionWithTypecode
) {
967 FtpSocketDataProviderDirectoryListing ctrl_socket
;
968 ExecuteTransaction(&ctrl_socket
, "ftp://host/;type=d", OK
);
970 EXPECT_TRUE(transaction_
.GetResponseInfo()->is_directory_listing
);
971 EXPECT_EQ(-1, transaction_
.GetResponseInfo()->expected_content_size
);
974 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcome
) {
975 FtpSocketDataProviderDirectoryListing ctrl_socket
;
976 ctrl_socket
.set_multiline_welcome(true);
977 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
980 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads2
) {
981 FtpSocketDataProviderDirectoryListing ctrl_socket
;
982 ctrl_socket
.set_short_read_limit(2);
983 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
986 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionShortReads5
) {
987 FtpSocketDataProviderDirectoryListing ctrl_socket
;
988 ctrl_socket
.set_short_read_limit(5);
989 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
992 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionMultilineWelcomeShort
) {
993 FtpSocketDataProviderDirectoryListing ctrl_socket
;
994 // The client will not consume all three 230 lines. That's good, we want to
995 // test that scenario.
996 ctrl_socket
.set_allow_unconsumed_reads(true);
997 ctrl_socket
.set_multiline_welcome(true);
998 ctrl_socket
.set_short_read_limit(5);
999 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1002 // Regression test for http://crbug.com/60555.
1003 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionZeroSize
) {
1004 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket
;
1005 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1008 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMS
) {
1009 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1010 ExecuteTransaction(&ctrl_socket
, "ftp://host/dir", OK
);
1013 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionVMSRootDirectory
) {
1014 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket
;
1015 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1018 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionTransferStarting
) {
1019 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket
;
1020 ExecuteTransaction(&ctrl_socket
, "ftp://host", OK
);
1023 TEST_P(FtpNetworkTransactionTest
, DownloadTransaction
) {
1024 FtpSocketDataProviderFileDownload ctrl_socket
;
1025 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1027 // We pass an artificial value of 18 as a response to the SIZE command.
1028 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1029 EXPECT_EQ((GetFamily() == AF_INET
) ? "127.0.0.1" : "::1",
1030 transaction_
.GetResponseInfo()->socket_address
.host());
1031 EXPECT_EQ(21, transaction_
.GetResponseInfo()->socket_address
.port());
1034 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithPasvFallback
) {
1035 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket
;
1036 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1038 // We pass an artificial value of 18 as a response to the SIZE command.
1039 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1042 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeA
) {
1043 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1044 ctrl_socket
.set_data_type('A');
1045 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=a", OK
);
1047 // We pass an artificial value of 18 as a response to the SIZE command.
1048 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1051 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionWithTypecodeI
) {
1052 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket
;
1053 ExecuteTransaction(&ctrl_socket
, "ftp://host/file;type=i", OK
);
1055 // We pass an artificial value of 18 as a response to the SIZE command.
1056 EXPECT_EQ(18, transaction_
.GetResponseInfo()->expected_content_size
);
1059 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionMultilineWelcome
) {
1060 FtpSocketDataProviderFileDownload ctrl_socket
;
1061 ctrl_socket
.set_multiline_welcome(true);
1062 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1065 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads2
) {
1066 FtpSocketDataProviderFileDownload ctrl_socket
;
1067 ctrl_socket
.set_short_read_limit(2);
1068 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1071 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionShortReads5
) {
1072 FtpSocketDataProviderFileDownload ctrl_socket
;
1073 ctrl_socket
.set_short_read_limit(5);
1074 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1077 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionZeroSize
) {
1078 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket
;
1079 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1082 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionCWD451
) {
1083 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket
;
1084 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1087 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionVMS
) {
1088 FtpSocketDataProviderVMSFileDownload ctrl_socket
;
1089 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1092 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionTransferStarting
) {
1093 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket
;
1094 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1097 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionInvalidResponse
) {
1098 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket
;
1099 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1102 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvReallyBadFormat
) {
1103 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,\r\n",
1104 FtpSocketDataProvider::PRE_QUIT
);
1105 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1108 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort1
) {
1109 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1110 FtpSocketDataProvider::PRE_QUIT
);
1111 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1114 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort2
) {
1115 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1116 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1117 FtpSocketDataProvider::PRE_QUIT
);
1118 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1121 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort3
) {
1122 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1123 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1124 FtpSocketDataProvider::PRE_QUIT
);
1125 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1128 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafePort4
) {
1129 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1130 FtpSocketDataProviderEvilPasv
ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1131 FtpSocketDataProvider::PRE_QUIT
);
1132 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1135 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilPasvUnsafeHost
) {
1136 FtpSocketDataProviderEvilPasv
ctrl_socket(
1137 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR
);
1138 ctrl_socket
.set_use_epsv(GetFamily() != AF_INET
);
1139 std::string
mock_data("mock-data");
1140 MockRead data_reads
[] = {
1141 MockRead(mock_data
.c_str()),
1143 StaticSocketDataProvider data_socket1
;
1144 StaticSocketDataProvider
data_socket2(data_reads
, arraysize(data_reads
),
1146 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket
);
1147 mock_socket_factory_
.AddSocketDataProvider(&data_socket1
);
1148 mock_socket_factory_
.AddSocketDataProvider(&data_socket2
);
1149 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1151 // Start the transaction.
1152 ASSERT_EQ(ERR_IO_PENDING
,
1153 transaction_
.Start(&request_info
, callback_
.callback(),
1155 ASSERT_EQ(OK
, callback_
.WaitForResult());
1157 // The transaction fires the callback when we can start reading data. That
1158 // means that the data socket should be open.
1159 MockTCPClientSocket
* data_socket
=
1160 static_cast<MockTCPClientSocket
*>(transaction_
.data_socket_
.get());
1161 ASSERT_TRUE(data_socket
);
1162 ASSERT_TRUE(data_socket
->IsConnected());
1164 // Even if the PASV response specified some other address, we connect
1165 // to the address we used for control connection (which could be 127.0.0.1
1166 // or ::1 depending on whether we use IPv6).
1167 for (AddressList::const_iterator it
= data_socket
->addresses().begin();
1168 it
!= data_socket
->addresses().end(); ++it
) {
1169 EXPECT_NE("10.1.2.3", it
->ToStringWithoutPort());
1173 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat1
) {
1174 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1175 if (GetFamily() == AF_INET
)
1178 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22)\r\n",
1179 FtpSocketDataProvider::PRE_QUIT
);
1180 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1183 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat2
) {
1184 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1185 if (GetFamily() == AF_INET
)
1188 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||\r\n",
1189 FtpSocketDataProvider::PRE_QUIT
);
1190 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1193 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat3
) {
1194 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1195 if (GetFamily() == AF_INET
)
1198 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan\r\n",
1199 FtpSocketDataProvider::PRE_QUIT
);
1200 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1203 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat4
) {
1204 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1205 if (GetFamily() == AF_INET
)
1208 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (||||)\r\n",
1209 FtpSocketDataProvider::PRE_QUIT
);
1210 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1213 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvReallyBadFormat5
) {
1214 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1215 if (GetFamily() == AF_INET
)
1218 // Breaking the string in the next line prevents MSVC warning C4125.
1219 const char response
[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1220 FtpSocketDataProviderEvilEpsv
ctrl_socket(response
, sizeof(response
)-1,
1221 FtpSocketDataProvider::PRE_QUIT
);
1222 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1225 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort1
) {
1226 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1227 if (GetFamily() == AF_INET
)
1230 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||22|)\r\n",
1231 FtpSocketDataProvider::PRE_QUIT
);
1232 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1235 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort2
) {
1236 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1237 if (GetFamily() == AF_INET
)
1240 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||258|)\r\n",
1241 FtpSocketDataProvider::PRE_QUIT
);
1242 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1245 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort3
) {
1246 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1247 if (GetFamily() == AF_INET
)
1250 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||772|)\r\n",
1251 FtpSocketDataProvider::PRE_QUIT
);
1252 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1255 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvUnsafePort4
) {
1256 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1257 if (GetFamily() == AF_INET
)
1260 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|||2049|)\r\n",
1261 FtpSocketDataProvider::PRE_QUIT
);
1262 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1265 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvWeirdSep
) {
1266 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1267 if (GetFamily() == AF_INET
)
1270 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$31744$)\r\n",
1271 FtpSocketDataProvider::PRE_RETR
);
1272 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1275 TEST_P(FtpNetworkTransactionTest
,
1276 DownloadTransactionEvilEpsvWeirdSepUnsafePort
) {
1277 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1278 if (GetFamily() == AF_INET
)
1281 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan ($$$317$)\r\n",
1282 FtpSocketDataProvider::PRE_QUIT
);
1283 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_UNSAFE_PORT
);
1286 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilEpsvIllegalHost
) {
1287 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1288 if (GetFamily() == AF_INET
)
1291 FtpSocketDataProviderEvilEpsv
ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1292 FtpSocketDataProvider::PRE_QUIT
);
1293 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1296 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadUsername
) {
1297 FtpSocketDataProviderEvilLogin
ctrl_socket("hello%0Aworld", "test");
1298 ExecuteTransaction(&ctrl_socket
, "ftp://hello%0Aworld:test@host/file", OK
);
1301 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilLoginBadPassword
) {
1302 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello%0Dworld");
1303 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%0Dworld@host/file", OK
);
1306 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInLogin
) {
1307 FtpSocketDataProviderEvilLogin
ctrl_socket("hello world", "test");
1308 ExecuteTransaction(&ctrl_socket
, "ftp://hello%20world:test@host/file", OK
);
1311 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionSpaceInPassword
) {
1312 FtpSocketDataProviderEvilLogin
ctrl_socket("test", "hello world");
1313 ExecuteTransaction(&ctrl_socket
, "ftp://test:hello%20world@host/file", OK
);
1316 TEST_P(FtpNetworkTransactionTest
, EvilRestartUser
) {
1317 FtpSocketDataProvider ctrl_socket1
;
1318 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1319 FtpSocketDataProvider::PRE_QUIT
,
1320 "530 Login authentication failed\r\n");
1321 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1323 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1325 ASSERT_EQ(ERR_IO_PENDING
,
1326 transaction_
.Start(&request_info
, callback_
.callback(),
1328 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1330 MockRead ctrl_reads
[] = {
1331 MockRead("220 host TestFTPd\r\n"),
1332 MockRead("221 Goodbye!\r\n"),
1333 MockRead(SYNCHRONOUS
, OK
),
1335 MockWrite ctrl_writes
[] = {
1336 MockWrite("QUIT\r\n"),
1338 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1339 ctrl_writes
, arraysize(ctrl_writes
));
1340 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1341 ASSERT_EQ(ERR_IO_PENDING
,
1342 transaction_
.RestartWithAuth(
1344 base::ASCIIToUTF16("foo\nownz0red"),
1345 base::ASCIIToUTF16("innocent")),
1346 callback_
.callback()));
1347 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1350 TEST_P(FtpNetworkTransactionTest
, EvilRestartPassword
) {
1351 FtpSocketDataProvider ctrl_socket1
;
1352 ctrl_socket1
.InjectFailure(FtpSocketDataProvider::PRE_PASSWD
,
1353 FtpSocketDataProvider::PRE_QUIT
,
1354 "530 Login authentication failed\r\n");
1355 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket1
);
1357 FtpRequestInfo request_info
= GetRequestInfo("ftp://host/file");
1359 ASSERT_EQ(ERR_IO_PENDING
,
1360 transaction_
.Start(&request_info
, callback_
.callback(),
1362 ASSERT_EQ(ERR_FTP_FAILED
, callback_
.WaitForResult());
1364 MockRead ctrl_reads
[] = {
1365 MockRead("220 host TestFTPd\r\n"),
1366 MockRead("331 User okay, send password\r\n"),
1367 MockRead("221 Goodbye!\r\n"),
1368 MockRead(SYNCHRONOUS
, OK
),
1370 MockWrite ctrl_writes
[] = {
1371 MockWrite("USER innocent\r\n"),
1372 MockWrite("QUIT\r\n"),
1374 StaticSocketDataProvider
ctrl_socket2(ctrl_reads
, arraysize(ctrl_reads
),
1375 ctrl_writes
, arraysize(ctrl_writes
));
1376 mock_socket_factory_
.AddSocketDataProvider(&ctrl_socket2
);
1377 ASSERT_EQ(ERR_IO_PENDING
,
1378 transaction_
.RestartWithAuth(
1379 AuthCredentials(base::ASCIIToUTF16("innocent"),
1380 base::ASCIIToUTF16("foo\nownz0red")),
1381 callback_
.callback()));
1382 EXPECT_EQ(ERR_MALFORMED_IDENTITY
, callback_
.WaitForResult());
1385 TEST_P(FtpNetworkTransactionTest
, Escaping
) {
1386 FtpSocketDataProviderEscaping ctrl_socket
;
1387 ExecuteTransaction(&ctrl_socket
, "ftp://host/%20%21%22%23%24%25%79%80%81",
1391 // Test for http://crbug.com/23794.
1392 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionEvilSize
) {
1393 // Try to overflow int64 in the response.
1394 FtpSocketDataProviderEvilSize
ctrl_socket(
1395 "213 99999999999999999999999999999999\r\n",
1396 FtpSocketDataProvider::PRE_QUIT
);
1397 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_INVALID_RESPONSE
);
1400 // Test for http://crbug.com/36360.
1401 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionBigSize
) {
1402 // Pass a valid, but large file size. The transaction should not fail.
1403 FtpSocketDataProviderEvilSize
ctrl_socket(
1404 "213 3204427776\r\n",
1405 FtpSocketDataProvider::PRE_CWD
);
1406 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", OK
);
1407 EXPECT_EQ(3204427776LL,
1408 transaction_
.GetResponseInfo()->expected_content_size
);
1411 // Regression test for http://crbug.com/25023.
1412 TEST_P(FtpNetworkTransactionTest
, CloseConnection
) {
1413 FtpSocketDataProviderCloseConnection ctrl_socket
;
1414 ExecuteTransaction(&ctrl_socket
, "ftp://host", ERR_EMPTY_RESPONSE
);
1417 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailUser
) {
1418 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1419 // Use unallocated 599 FTP error code to make sure it falls into the generic
1420 // ERR_FTP_FAILED bucket.
1421 TransactionFailHelper(&ctrl_socket
,
1423 FtpSocketDataProvider::PRE_USER
,
1424 FtpSocketDataProvider::PRE_QUIT
,
1429 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass
) {
1430 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1431 TransactionFailHelper(&ctrl_socket
,
1433 FtpSocketDataProvider::PRE_PASSWD
,
1434 FtpSocketDataProvider::PRE_QUIT
,
1435 "530 Login authentication failed\r\n",
1439 // Regression test for http://crbug.com/38707.
1440 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPass503
) {
1441 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1442 TransactionFailHelper(&ctrl_socket
,
1444 FtpSocketDataProvider::PRE_PASSWD
,
1445 FtpSocketDataProvider::PRE_QUIT
,
1446 "503 Bad sequence of commands\r\n",
1447 ERR_FTP_BAD_COMMAND_SEQUENCE
);
1450 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailSyst
) {
1451 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1452 // Use unallocated 599 FTP error code to make sure it falls into the generic
1453 // ERR_FTP_FAILED bucket.
1454 TransactionFailHelper(&ctrl_socket
,
1456 FtpSocketDataProvider::PRE_SYST
,
1457 FtpSocketDataProvider::PRE_PWD
,
1462 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailPwd
) {
1463 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1464 // Use unallocated 599 FTP error code to make sure it falls into the generic
1465 // ERR_FTP_FAILED bucket.
1466 TransactionFailHelper(&ctrl_socket
,
1468 FtpSocketDataProvider::PRE_PWD
,
1469 FtpSocketDataProvider::PRE_QUIT
,
1474 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailType
) {
1475 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1476 // Use unallocated 599 FTP error code to make sure it falls into the generic
1477 // ERR_FTP_FAILED bucket.
1478 TransactionFailHelper(&ctrl_socket
,
1480 FtpSocketDataProvider::PRE_TYPE
,
1481 FtpSocketDataProvider::PRE_QUIT
,
1486 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailEpsv
) {
1487 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1488 if (GetFamily() == AF_INET
)
1491 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1492 // Use unallocated 599 FTP error code to make sure it falls into the generic
1493 // ERR_FTP_FAILED bucket.
1494 TransactionFailHelper(
1495 &ctrl_socket
, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV
,
1496 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1499 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailCwd
) {
1500 FtpSocketDataProviderDirectoryListing ctrl_socket
;
1501 // Use unallocated 599 FTP error code to make sure it falls into the generic
1502 // ERR_FTP_FAILED bucket.
1503 TransactionFailHelper(&ctrl_socket
,
1505 FtpSocketDataProvider::PRE_CWD
,
1506 FtpSocketDataProvider::PRE_QUIT
,
1511 TEST_P(FtpNetworkTransactionTest
, DirectoryTransactionFailList
) {
1512 FtpSocketDataProviderVMSDirectoryListing ctrl_socket
;
1513 // Use unallocated 599 FTP error code to make sure it falls into the generic
1514 // ERR_FTP_FAILED bucket.
1515 TransactionFailHelper(&ctrl_socket
,
1517 FtpSocketDataProvider::PRE_LIST
,
1518 FtpSocketDataProvider::PRE_QUIT
,
1523 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailUser
) {
1524 FtpSocketDataProviderFileDownload ctrl_socket
;
1525 // Use unallocated 599 FTP error code to make sure it falls into the generic
1526 // ERR_FTP_FAILED bucket.
1527 TransactionFailHelper(&ctrl_socket
,
1529 FtpSocketDataProvider::PRE_USER
,
1530 FtpSocketDataProvider::PRE_QUIT
,
1535 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPass
) {
1536 FtpSocketDataProviderFileDownload ctrl_socket
;
1537 TransactionFailHelper(&ctrl_socket
,
1539 FtpSocketDataProvider::PRE_PASSWD
,
1540 FtpSocketDataProvider::PRE_QUIT
,
1541 "530 Login authentication failed\r\n",
1545 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailSyst
) {
1546 FtpSocketDataProviderFileDownload ctrl_socket
;
1547 // Use unallocated 599 FTP error code to make sure it falls into the generic
1548 // ERR_FTP_FAILED bucket.
1549 TransactionFailHelper(&ctrl_socket
,
1551 FtpSocketDataProvider::PRE_SYST
,
1552 FtpSocketDataProvider::PRE_PWD
,
1557 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailPwd
) {
1558 FtpSocketDataProviderFileDownload ctrl_socket
;
1559 // Use unallocated 599 FTP error code to make sure it falls into the generic
1560 // ERR_FTP_FAILED bucket.
1561 TransactionFailHelper(&ctrl_socket
,
1563 FtpSocketDataProvider::PRE_PWD
,
1564 FtpSocketDataProvider::PRE_QUIT
,
1569 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailType
) {
1570 FtpSocketDataProviderFileDownload ctrl_socket
;
1571 // Use unallocated 599 FTP error code to make sure it falls into the generic
1572 // ERR_FTP_FAILED bucket.
1573 TransactionFailHelper(&ctrl_socket
,
1575 FtpSocketDataProvider::PRE_TYPE
,
1576 FtpSocketDataProvider::PRE_QUIT
,
1581 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailEpsv
) {
1582 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1583 if (GetFamily() == AF_INET
)
1586 FtpSocketDataProviderFileDownload ctrl_socket
;
1587 // Use unallocated 599 FTP error code to make sure it falls into the generic
1588 // ERR_FTP_FAILED bucket.
1589 TransactionFailHelper(
1590 &ctrl_socket
, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV
,
1591 FtpSocketDataProvider::PRE_NOPASV
, "599 fail\r\n", ERR_FTP_FAILED
);
1594 TEST_P(FtpNetworkTransactionTest
, DownloadTransactionFailRetr
) {
1595 FtpSocketDataProviderFileDownload ctrl_socket
;
1596 // Use unallocated 599 FTP error code to make sure it falls into the generic
1597 // ERR_FTP_FAILED bucket.
1598 TransactionFailHelper(&ctrl_socket
,
1600 FtpSocketDataProvider::PRE_RETR
,
1601 FtpSocketDataProvider::PRE_QUIT
,
1606 TEST_P(FtpNetworkTransactionTest
, FileNotFound
) {
1607 FtpSocketDataProviderFileNotFound ctrl_socket
;
1608 ExecuteTransaction(&ctrl_socket
, "ftp://host/file", ERR_FTP_FAILED
);
1611 // Test for http://crbug.com/38845.
1612 TEST_P(FtpNetworkTransactionTest
, ZeroLengthDirInPWD
) {
1613 FtpSocketDataProviderFileDownload ctrl_socket
;
1614 TransactionFailHelper(&ctrl_socket
,
1616 FtpSocketDataProvider::PRE_PWD
,
1617 FtpSocketDataProvider::PRE_TYPE
,
1622 INSTANTIATE_TEST_CASE_P(FTP
,
1623 FtpNetworkTransactionTest
,
1624 ::testing::Values(AF_INET
, AF_INET6
));