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