Remove use of TextView.getMaxLines to restore ICS compatibility
[chromium-blink-merge.git] / net / ftp / ftp_network_transaction_unittest.cc
blob79e16877bdd19d4ddd214cd66c288a1b415c46e0
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"
25 namespace {
27 // Size we use for IOBuffers used to receive data from the test data socket.
28 const int kBufferSize = 128;
30 } // namespace
32 namespace net {
34 class FtpSocketDataProvider : public DynamicSocketDataProvider {
35 public:
36 enum State {
37 NONE,
38 PRE_USER,
39 PRE_PASSWD,
40 PRE_SYST,
41 PRE_PWD,
42 PRE_TYPE,
43 PRE_SIZE,
44 PRE_LIST_EPSV,
45 PRE_LIST_PASV,
46 PRE_LIST,
47 PRE_RETR,
48 PRE_RETR_EPSV,
49 PRE_RETR_PASV,
50 PRE_CWD,
51 PRE_QUIT,
52 PRE_NOPASV,
53 QUIT
56 FtpSocketDataProvider()
57 : failure_injection_state_(NONE),
58 multiline_welcome_(false),
59 use_epsv_(true),
60 data_type_('I') {
61 Init();
64 MockWriteResult OnWrite(const std::string& data) override {
65 if (InjectFault())
66 return MockWriteResult(ASYNC, data.length());
67 switch (state()) {
68 case PRE_USER:
69 return Verify("USER anonymous\r\n", data, PRE_PASSWD,
70 "331 Password needed\r\n");
71 case PRE_PASSWD:
73 static const char response_one[] = "230 Welcome\r\n";
74 static const char response_multi[] =
75 "230- One\r\n230- Two\r\n230 Three\r\n";
76 return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
77 multiline_welcome_ ? response_multi : response_one);
79 case PRE_SYST:
80 return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
81 case PRE_PWD:
82 return Verify("PWD\r\n", data, PRE_TYPE,
83 "257 \"/\" is your current location\r\n");
84 case PRE_TYPE:
85 return Verify(std::string("TYPE ") + data_type_ + "\r\n", data,
86 PRE_SIZE, "200 TYPE set successfully\r\n");
87 case PRE_LIST_EPSV:
88 return Verify("EPSV\r\n", data, PRE_LIST,
89 "227 Entering Extended Passive Mode (|||31744|)\r\n");
90 case PRE_LIST_PASV:
91 return Verify("PASV\r\n", data, PRE_LIST,
92 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
93 case PRE_RETR_EPSV:
94 return Verify("EPSV\r\n", data, PRE_RETR,
95 "227 Entering Extended Passive Mode (|||31744|)\r\n");
96 case PRE_RETR_PASV:
97 return Verify("PASV\r\n", data, PRE_RETR,
98 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
99 case PRE_NOPASV:
100 // Use unallocated 599 FTP error code to make sure it falls into the
101 // generic ERR_FTP_FAILED bucket.
102 return Verify("PASV\r\n", data, PRE_QUIT,
103 "599 fail\r\n");
104 case PRE_QUIT:
105 return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
106 default:
107 NOTREACHED() << "State not handled " << state();
108 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
112 void InjectFailure(State state, State next_state, const char* response) {
113 DCHECK_EQ(NONE, failure_injection_state_);
114 DCHECK_NE(NONE, state);
115 DCHECK_NE(NONE, next_state);
116 DCHECK_NE(state, next_state);
117 failure_injection_state_ = state;
118 failure_injection_next_state_ = next_state;
119 fault_response_ = response;
122 State state() const {
123 return state_;
126 void Reset() override {
127 DynamicSocketDataProvider::Reset();
128 Init();
131 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; }
133 bool use_epsv() const { return use_epsv_; }
134 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; }
136 void set_data_type(char data_type) { data_type_ = data_type; }
138 protected:
139 void Init() {
140 state_ = PRE_USER;
141 SimulateRead("220 host TestFTPd\r\n");
144 // If protocol fault injection has been requested, adjusts state and mocked
145 // read and returns true.
146 bool InjectFault() {
147 if (state_ != failure_injection_state_)
148 return false;
149 SimulateRead(fault_response_);
150 state_ = failure_injection_next_state_;
151 return true;
154 MockWriteResult Verify(const std::string& expected,
155 const std::string& data,
156 State next_state,
157 const char* next_read,
158 const size_t next_read_length) {
159 EXPECT_EQ(expected, data);
160 if (expected == data) {
161 state_ = next_state;
162 SimulateRead(next_read, next_read_length);
163 return MockWriteResult(ASYNC, data.length());
165 return MockWriteResult(ASYNC, ERR_UNEXPECTED);
168 MockWriteResult Verify(const std::string& expected,
169 const std::string& data,
170 State next_state,
171 const char* next_read) {
172 return Verify(expected, data, next_state,
173 next_read, std::strlen(next_read));
177 private:
178 State state_;
179 State failure_injection_state_;
180 State failure_injection_next_state_;
181 const char* fault_response_;
183 // If true, we will send multiple 230 lines as response after PASS.
184 bool multiline_welcome_;
186 // If true, we will use EPSV command.
187 bool use_epsv_;
189 // Data type to be used for TYPE command.
190 char data_type_;
192 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
195 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
196 public:
197 FtpSocketDataProviderDirectoryListing() {
200 MockWriteResult OnWrite(const std::string& data) override {
201 if (InjectFault())
202 return MockWriteResult(ASYNC, data.length());
203 switch (state()) {
204 case PRE_SIZE:
205 return Verify("SIZE /\r\n", data, PRE_CWD,
206 "550 I can only retrieve regular files\r\n");
207 case PRE_CWD:
208 return Verify("CWD /\r\n", data,
209 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
210 case PRE_LIST:
211 return Verify("LIST -l\r\n", data, PRE_QUIT, "200 OK\r\n");
212 default:
213 return FtpSocketDataProvider::OnWrite(data);
217 private:
218 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
221 class FtpSocketDataProviderDirectoryListingWithPasvFallback
222 : public FtpSocketDataProviderDirectoryListing {
223 public:
224 FtpSocketDataProviderDirectoryListingWithPasvFallback() {
227 MockWriteResult OnWrite(const std::string& data) override {
228 if (InjectFault())
229 return MockWriteResult(ASYNC, data.length());
230 switch (state()) {
231 case PRE_LIST_EPSV:
232 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
233 "500 no EPSV for you\r\n");
234 case PRE_SIZE:
235 return Verify("SIZE /\r\n", data, PRE_CWD,
236 "550 I can only retrieve regular files\r\n");
237 default:
238 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
242 private:
243 DISALLOW_COPY_AND_ASSIGN(
244 FtpSocketDataProviderDirectoryListingWithPasvFallback);
247 class FtpSocketDataProviderDirectoryListingZeroSize
248 : public FtpSocketDataProviderDirectoryListing {
249 public:
250 FtpSocketDataProviderDirectoryListingZeroSize() {
253 MockWriteResult OnWrite(const std::string& data) override {
254 if (InjectFault())
255 return MockWriteResult(ASYNC, data.length());
256 switch (state()) {
257 case PRE_SIZE:
258 return Verify("SIZE /\r\n", data, PRE_CWD, "213 0\r\n");
259 default:
260 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
264 private:
265 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize);
268 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
269 public:
270 FtpSocketDataProviderVMSDirectoryListing() {
273 MockWriteResult OnWrite(const std::string& data) override {
274 if (InjectFault())
275 return MockWriteResult(ASYNC, data.length());
276 switch (state()) {
277 case PRE_SYST:
278 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
279 case PRE_PWD:
280 return Verify("PWD\r\n", data, PRE_TYPE,
281 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
282 case PRE_LIST_EPSV:
283 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
284 "500 Invalid command\r\n");
285 case PRE_SIZE:
286 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_CWD,
287 "550 I can only retrieve regular files\r\n");
288 case PRE_CWD:
289 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data,
290 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
291 case PRE_LIST:
292 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
293 default:
294 return FtpSocketDataProvider::OnWrite(data);
298 private:
299 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
302 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
303 : public FtpSocketDataProvider {
304 public:
305 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
308 MockWriteResult OnWrite(const std::string& data) override {
309 if (InjectFault())
310 return MockWriteResult(ASYNC, data.length());
311 switch (state()) {
312 case PRE_SYST:
313 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
314 case PRE_PWD:
315 return Verify("PWD\r\n", data, PRE_TYPE,
316 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
317 case PRE_LIST_EPSV:
318 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
319 "500 EPSV command unknown\r\n");
320 case PRE_SIZE:
321 return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_CWD,
322 "550 I can only retrieve regular files\r\n");
323 case PRE_CWD:
324 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data,
325 use_epsv() ? PRE_LIST_EPSV : PRE_LIST_PASV, "200 OK\r\n");
326 case PRE_LIST:
327 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
328 default:
329 return FtpSocketDataProvider::OnWrite(data);
333 private:
334 DISALLOW_COPY_AND_ASSIGN(
335 FtpSocketDataProviderVMSDirectoryListingRootDirectory);
338 class FtpSocketDataProviderFileDownloadWithFileTypecode
339 : public FtpSocketDataProvider {
340 public:
341 FtpSocketDataProviderFileDownloadWithFileTypecode() {
344 MockWriteResult OnWrite(const std::string& data) override {
345 if (InjectFault())
346 return MockWriteResult(ASYNC, data.length());
347 switch (state()) {
348 case PRE_SIZE:
349 return Verify("SIZE /file\r\n", data,
350 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV, "213 18\r\n");
351 case PRE_RETR:
352 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
353 default:
354 return FtpSocketDataProvider::OnWrite(data);
358 private:
359 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode);
362 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
363 public:
364 FtpSocketDataProviderFileDownload() {
367 MockWriteResult OnWrite(const std::string& data) override {
368 if (InjectFault())
369 return MockWriteResult(ASYNC, data.length());
370 switch (state()) {
371 case PRE_SIZE:
372 return Verify("SIZE /file\r\n", data, PRE_CWD, "213 18\r\n");
373 case PRE_CWD:
374 return Verify("CWD /file\r\n", data,
375 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
376 "550 Not a directory\r\n");
377 case PRE_RETR:
378 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
379 default:
380 return FtpSocketDataProvider::OnWrite(data);
384 private:
385 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
388 class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider {
389 public:
390 FtpSocketDataProviderFileNotFound() {
393 MockWriteResult OnWrite(const std::string& data) override {
394 if (InjectFault())
395 return MockWriteResult(ASYNC, data.length());
396 switch (state()) {
397 case PRE_SIZE:
398 return Verify("SIZE /file\r\n", data, PRE_CWD,
399 "550 File Not Found\r\n");
400 case PRE_CWD:
401 return Verify("CWD /file\r\n", data,
402 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
403 "550 File Not Found\r\n");
404 case PRE_RETR:
405 return Verify("RETR /file\r\n", data, PRE_QUIT,
406 "550 File Not Found\r\n");
407 default:
408 return FtpSocketDataProvider::OnWrite(data);
412 private:
413 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound);
416 class FtpSocketDataProviderFileDownloadWithPasvFallback
417 : public FtpSocketDataProviderFileDownload {
418 public:
419 FtpSocketDataProviderFileDownloadWithPasvFallback() {
422 MockWriteResult OnWrite(const std::string& data) override {
423 if (InjectFault())
424 return MockWriteResult(ASYNC, data.length());
425 switch (state()) {
426 case PRE_RETR_EPSV:
427 return Verify("EPSV\r\n", data, PRE_RETR_PASV, "500 No can do\r\n");
428 case PRE_CWD:
429 return Verify("CWD /file\r\n", data,
430 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
431 "550 Not a directory\r\n");
432 default:
433 return FtpSocketDataProviderFileDownload::OnWrite(data);
437 private:
438 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback);
441 class FtpSocketDataProviderFileDownloadZeroSize
442 : public FtpSocketDataProviderFileDownload {
443 public:
444 FtpSocketDataProviderFileDownloadZeroSize() {
447 MockWriteResult OnWrite(const std::string& data) override {
448 if (InjectFault())
449 return MockWriteResult(ASYNC, data.length());
450 switch (state()) {
451 case PRE_SIZE:
452 return Verify("SIZE /file\r\n", data, PRE_CWD,
453 "213 0\r\n");
454 case PRE_CWD:
455 return Verify("CWD /file\r\n", data,
456 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
457 "550 not a directory\r\n");
458 default:
459 return FtpSocketDataProviderFileDownload::OnWrite(data);
463 private:
464 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize);
467 class FtpSocketDataProviderFileDownloadCWD451
468 : public FtpSocketDataProviderFileDownload {
469 public:
470 FtpSocketDataProviderFileDownloadCWD451() {
473 MockWriteResult OnWrite(const std::string& data) override {
474 if (InjectFault())
475 return MockWriteResult(ASYNC, data.length());
476 switch (state()) {
477 case PRE_CWD:
478 return Verify("CWD /file\r\n", data,
479 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
480 "451 not a directory\r\n");
481 default:
482 return FtpSocketDataProviderFileDownload::OnWrite(data);
486 private:
487 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451);
490 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
491 public:
492 FtpSocketDataProviderVMSFileDownload() {
495 MockWriteResult OnWrite(const std::string& data) override {
496 if (InjectFault())
497 return MockWriteResult(ASYNC, data.length());
498 switch (state()) {
499 case PRE_SYST:
500 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
501 case PRE_PWD:
502 return Verify("PWD\r\n", data, PRE_TYPE,
503 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
504 case PRE_LIST_EPSV:
505 return Verify("EPSV\r\n", data, PRE_LIST_PASV,
506 "500 EPSV command unknown\r\n");
507 case PRE_SIZE:
508 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD,
509 "213 18\r\n");
510 case PRE_CWD:
511 return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data,
512 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
513 "550 Not a directory\r\n");
514 case PRE_RETR:
515 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
516 "200 OK\r\n");
517 default:
518 return FtpSocketDataProvider::OnWrite(data);
522 private:
523 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
526 class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload {
527 public:
528 FtpSocketDataProviderEscaping() {
531 MockWriteResult OnWrite(const std::string& data) override {
532 if (InjectFault())
533 return MockWriteResult(ASYNC, data.length());
534 switch (state()) {
535 case PRE_SIZE:
536 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD,
537 "213 18\r\n");
538 case PRE_CWD:
539 return Verify("CWD / !\"#$%y\200\201\r\n", data,
540 use_epsv() ? PRE_RETR_EPSV : PRE_RETR_PASV,
541 "550 Not a directory\r\n");
542 case PRE_RETR:
543 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
544 "200 OK\r\n");
545 default:
546 return FtpSocketDataProviderFileDownload::OnWrite(data);
550 private:
551 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
554 class FtpSocketDataProviderFileDownloadTransferStarting
555 : public FtpSocketDataProviderFileDownload {
556 public:
557 FtpSocketDataProviderFileDownloadTransferStarting() {
560 MockWriteResult OnWrite(const std::string& data) override {
561 if (InjectFault())
562 return MockWriteResult(ASYNC, data.length());
563 switch (state()) {
564 case PRE_RETR:
565 return Verify("RETR /file\r\n", data, PRE_QUIT,
566 "125-Data connection already open.\r\n"
567 "125 Transfer starting.\r\n"
568 "226 Transfer complete.\r\n");
569 default:
570 return FtpSocketDataProviderFileDownload::OnWrite(data);
574 private:
575 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
578 class FtpSocketDataProviderDirectoryListingTransferStarting
579 : public FtpSocketDataProviderDirectoryListing {
580 public:
581 FtpSocketDataProviderDirectoryListingTransferStarting() {
584 MockWriteResult OnWrite(const std::string& data) override {
585 if (InjectFault())
586 return MockWriteResult(ASYNC, data.length());
587 switch (state()) {
588 case PRE_LIST:
589 return Verify("LIST -l\r\n", data, PRE_QUIT,
590 "125-Data connection already open.\r\n"
591 "125 Transfer starting.\r\n"
592 "226 Transfer complete.\r\n");
593 default:
594 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
598 private:
599 DISALLOW_COPY_AND_ASSIGN(
600 FtpSocketDataProviderDirectoryListingTransferStarting);
603 class FtpSocketDataProviderFileDownloadInvalidResponse
604 : public FtpSocketDataProviderFileDownload {
605 public:
606 FtpSocketDataProviderFileDownloadInvalidResponse() {
609 MockWriteResult OnWrite(const std::string& data) override {
610 if (InjectFault())
611 return MockWriteResult(ASYNC, data.length());
612 switch (state()) {
613 case PRE_SIZE:
614 // Use unallocated 599 FTP error code to make sure it falls into the
615 // generic ERR_FTP_FAILED bucket.
616 return Verify("SIZE /file\r\n", data, PRE_QUIT,
617 "599 Evil Response\r\n"
618 "599 More Evil\r\n");
619 default:
620 return FtpSocketDataProviderFileDownload::OnWrite(data);
624 private:
625 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
628 class FtpSocketDataProviderEvilEpsv : public FtpSocketDataProviderFileDownload {
629 public:
630 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
631 State expected_state)
632 : epsv_response_(epsv_response),
633 epsv_response_length_(std::strlen(epsv_response)),
634 expected_state_(expected_state) {}
636 FtpSocketDataProviderEvilEpsv(const char* epsv_response,
637 size_t epsv_response_length,
638 State expected_state)
639 : epsv_response_(epsv_response),
640 epsv_response_length_(epsv_response_length),
641 expected_state_(expected_state) {}
643 MockWriteResult OnWrite(const std::string& data) override {
644 if (InjectFault())
645 return MockWriteResult(ASYNC, data.length());
646 switch (state()) {
647 case PRE_RETR_EPSV:
648 return Verify("EPSV\r\n", data, expected_state_,
649 epsv_response_, epsv_response_length_);
650 default:
651 return FtpSocketDataProviderFileDownload::OnWrite(data);
655 private:
656 const char* epsv_response_;
657 const size_t epsv_response_length_;
658 const State expected_state_;
660 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv);
663 class FtpSocketDataProviderEvilPasv
664 : public FtpSocketDataProviderFileDownloadWithPasvFallback {
665 public:
666 FtpSocketDataProviderEvilPasv(const char* pasv_response, State expected_state)
667 : pasv_response_(pasv_response),
668 expected_state_(expected_state) {
671 MockWriteResult OnWrite(const std::string& data) override {
672 if (InjectFault())
673 return MockWriteResult(ASYNC, data.length());
674 switch (state()) {
675 case PRE_RETR_PASV:
676 return Verify("PASV\r\n", data, expected_state_, pasv_response_);
677 default:
678 return FtpSocketDataProviderFileDownloadWithPasvFallback::OnWrite(data);
682 private:
683 const char* pasv_response_;
684 const State expected_state_;
686 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
689 class FtpSocketDataProviderEvilSize : public FtpSocketDataProviderFileDownload {
690 public:
691 FtpSocketDataProviderEvilSize(const char* size_response, State expected_state)
692 : size_response_(size_response),
693 expected_state_(expected_state) {
696 MockWriteResult OnWrite(const std::string& data) override {
697 if (InjectFault())
698 return MockWriteResult(ASYNC, data.length());
699 switch (state()) {
700 case PRE_SIZE:
701 return Verify("SIZE /file\r\n", data, expected_state_, size_response_);
702 default:
703 return FtpSocketDataProviderFileDownload::OnWrite(data);
707 private:
708 const char* size_response_;
709 const State expected_state_;
711 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize);
714 class FtpSocketDataProviderEvilLogin
715 : public FtpSocketDataProviderFileDownload {
716 public:
717 FtpSocketDataProviderEvilLogin(const char* expected_user,
718 const char* expected_password)
719 : expected_user_(expected_user),
720 expected_password_(expected_password) {
723 MockWriteResult OnWrite(const std::string& data) override {
724 if (InjectFault())
725 return MockWriteResult(ASYNC, data.length());
726 switch (state()) {
727 case PRE_USER:
728 return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
729 PRE_PASSWD, "331 Password needed\r\n");
730 case PRE_PASSWD:
731 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
732 PRE_SYST, "230 Welcome\r\n");
733 default:
734 return FtpSocketDataProviderFileDownload::OnWrite(data);
738 private:
739 const char* expected_user_;
740 const char* expected_password_;
742 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
745 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
746 public:
747 FtpSocketDataProviderCloseConnection() {
750 MockWriteResult OnWrite(const std::string& data) override {
751 if (InjectFault())
752 return MockWriteResult(ASYNC, data.length());
753 switch (state()) {
754 case PRE_USER:
755 return Verify("USER anonymous\r\n", data,
756 PRE_QUIT, "");
757 default:
758 return FtpSocketDataProvider::OnWrite(data);
762 private:
763 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
766 class FtpNetworkTransactionTest
767 : public PlatformTest,
768 public ::testing::WithParamInterface<int> {
769 public:
770 FtpNetworkTransactionTest()
771 : host_resolver_(new MockHostResolver),
772 session_(new FtpNetworkSession(host_resolver_.get())),
773 transaction_(session_.get(), &mock_socket_factory_) {
774 scoped_refptr<RuleBasedHostResolverProc> rules(
775 new RuleBasedHostResolverProc(NULL));
776 if (GetFamily() == AF_INET) {
777 rules->AddIPLiteralRule("*", "127.0.0.1", "127.0.0.1");
778 } else if (GetFamily() == AF_INET6) {
779 rules->AddIPLiteralRule("*", "::1", "::1");
780 } else {
781 NOTREACHED();
783 host_resolver_->set_rules(rules.get());
786 protected:
787 // Accessor to make code refactoring-friendly, e.g. when we change the way
788 // parameters are passed (like more parameters).
789 int GetFamily() {
790 return GetParam();
793 FtpRequestInfo GetRequestInfo(const std::string& url) {
794 FtpRequestInfo info;
795 info.url = GURL(url);
796 return info;
799 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
800 const char* request,
801 int expected_result) {
802 // Expect EPSV usage for non-IPv4 control connections.
803 ctrl_socket->set_use_epsv((GetFamily() != AF_INET));
805 mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
807 std::string mock_data("mock-data");
808 MockRead data_reads[] = {
809 // Usually FTP servers close the data connection after the entire data has
810 // been received.
811 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
812 MockRead(mock_data.c_str()),
815 scoped_ptr<StaticSocketDataProvider> data_socket(
816 new StaticSocketDataProvider(data_reads, arraysize(data_reads), NULL,
817 0));
818 mock_socket_factory_.AddSocketDataProvider(data_socket.get());
819 FtpRequestInfo request_info = GetRequestInfo(request);
820 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
821 ASSERT_EQ(ERR_IO_PENDING,
822 transaction_.Start(&request_info, callback_.callback(),
823 BoundNetLog()));
824 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
825 ASSERT_EQ(expected_result, callback_.WaitForResult());
826 if (expected_result == OK) {
827 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
828 memset(io_buffer->data(), 0, kBufferSize);
829 ASSERT_EQ(ERR_IO_PENDING,
830 transaction_.Read(io_buffer.get(), kBufferSize,
831 callback_.callback()));
832 ASSERT_EQ(static_cast<int>(mock_data.length()),
833 callback_.WaitForResult());
834 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
836 // Do another Read to detect that the data socket is now closed.
837 int rv = transaction_.Read(io_buffer.get(), kBufferSize,
838 callback_.callback());
839 if (rv == ERR_IO_PENDING) {
840 EXPECT_EQ(0, callback_.WaitForResult());
841 } else {
842 EXPECT_EQ(0, rv);
845 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
846 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
849 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
850 const char* request,
851 FtpSocketDataProvider::State state,
852 FtpSocketDataProvider::State next_state,
853 const char* response,
854 int expected_result) {
855 ctrl_socket->InjectFailure(state, next_state, response);
856 ExecuteTransaction(ctrl_socket, request, expected_result);
859 scoped_ptr<MockHostResolver> host_resolver_;
860 scoped_refptr<FtpNetworkSession> session_;
861 MockClientSocketFactory mock_socket_factory_;
862 FtpNetworkTransaction transaction_;
863 TestCompletionCallback callback_;
866 TEST_P(FtpNetworkTransactionTest, FailedLookup) {
867 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
868 scoped_refptr<RuleBasedHostResolverProc> rules(
869 new RuleBasedHostResolverProc(NULL));
870 rules->AddSimulatedFailure("badhost");
871 host_resolver_->set_rules(rules.get());
873 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
874 ASSERT_EQ(ERR_IO_PENDING,
875 transaction_.Start(&request_info, callback_.callback(),
876 BoundNetLog()));
877 ASSERT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
878 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
881 // Check that when determining the host, the square brackets decorating IPv6
882 // literals in URLs are stripped.
883 TEST_P(FtpNetworkTransactionTest, StripBracketsFromIPv6Literals) {
884 // This test only makes sense for IPv6 connections.
885 if (GetFamily() != AF_INET6)
886 return;
888 host_resolver_->rules()->AddSimulatedFailure("[::1]");
890 // We start a transaction that is expected to fail with ERR_INVALID_RESPONSE.
891 // The important part of this test is to make sure that we don't fail with
892 // ERR_NAME_NOT_RESOLVED, since that would mean the decorated hostname
893 // was used.
894 FtpSocketDataProviderEvilSize ctrl_socket(
895 "213 99999999999999999999999999999999\r\n",
896 FtpSocketDataProvider::PRE_QUIT);
897 ExecuteTransaction(&ctrl_socket, "ftp://[::1]/file", ERR_INVALID_RESPONSE);
900 TEST_P(FtpNetworkTransactionTest, DirectoryTransaction) {
901 FtpSocketDataProviderDirectoryListing ctrl_socket;
902 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
904 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
905 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
906 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
907 transaction_.GetResponseInfo()->socket_address.host());
908 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
911 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) {
912 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket;
913 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
915 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
916 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
919 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) {
920 FtpSocketDataProviderDirectoryListing ctrl_socket;
921 ExecuteTransaction(&ctrl_socket, "ftp://host/;type=d", OK);
923 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing);
924 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size);
927 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
928 FtpSocketDataProviderDirectoryListing ctrl_socket;
929 ctrl_socket.set_multiline_welcome(true);
930 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
933 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
934 FtpSocketDataProviderDirectoryListing ctrl_socket;
935 ctrl_socket.set_short_read_limit(2);
936 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
939 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
940 FtpSocketDataProviderDirectoryListing ctrl_socket;
941 ctrl_socket.set_short_read_limit(5);
942 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
945 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
946 FtpSocketDataProviderDirectoryListing ctrl_socket;
947 // The client will not consume all three 230 lines. That's good, we want to
948 // test that scenario.
949 ctrl_socket.allow_unconsumed_reads(true);
950 ctrl_socket.set_multiline_welcome(true);
951 ctrl_socket.set_short_read_limit(5);
952 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
955 // Regression test for http://crbug.com/60555.
956 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) {
957 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket;
958 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
961 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
962 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
963 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
966 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
967 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
968 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
971 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
972 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
973 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
976 TEST_P(FtpNetworkTransactionTest, DownloadTransaction) {
977 FtpSocketDataProviderFileDownload ctrl_socket;
978 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
980 // We pass an artificial value of 18 as a response to the SIZE command.
981 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
982 EXPECT_EQ((GetFamily() == AF_INET) ? "127.0.0.1" : "::1",
983 transaction_.GetResponseInfo()->socket_address.host());
984 EXPECT_EQ(21, transaction_.GetResponseInfo()->socket_address.port());
987 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) {
988 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket;
989 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
991 // We pass an artificial value of 18 as a response to the SIZE command.
992 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
995 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) {
996 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
997 ctrl_socket.set_data_type('A');
998 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK);
1000 // We pass an artificial value of 18 as a response to the SIZE command.
1001 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1004 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) {
1005 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket;
1006 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK);
1008 // We pass an artificial value of 18 as a response to the SIZE command.
1009 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size);
1012 TEST_P(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
1013 FtpSocketDataProviderFileDownload ctrl_socket;
1014 ctrl_socket.set_multiline_welcome(true);
1015 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1018 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
1019 FtpSocketDataProviderFileDownload ctrl_socket;
1020 ctrl_socket.set_short_read_limit(2);
1021 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1024 TEST_P(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
1025 FtpSocketDataProviderFileDownload ctrl_socket;
1026 ctrl_socket.set_short_read_limit(5);
1027 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1030 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) {
1031 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket;
1032 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1035 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) {
1036 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket;
1037 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1040 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) {
1041 FtpSocketDataProviderVMSFileDownload ctrl_socket;
1042 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1045 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
1046 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
1047 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1050 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
1051 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
1052 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1055 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvReallyBadFormat) {
1056 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,\r\n",
1057 FtpSocketDataProvider::PRE_QUIT);
1058 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1061 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
1062 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
1063 FtpSocketDataProvider::PRE_QUIT);
1064 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1067 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
1068 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
1069 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
1070 FtpSocketDataProvider::PRE_QUIT);
1071 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1074 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
1075 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
1076 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
1077 FtpSocketDataProvider::PRE_QUIT);
1078 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1081 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
1082 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
1083 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
1084 FtpSocketDataProvider::PRE_QUIT);
1085 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1088 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
1089 FtpSocketDataProviderEvilPasv ctrl_socket(
1090 "227 Portscan (10,1,2,3,123,456)\r\n", FtpSocketDataProvider::PRE_RETR);
1091 ctrl_socket.set_use_epsv(GetFamily() != AF_INET);
1092 std::string mock_data("mock-data");
1093 MockRead data_reads[] = {
1094 MockRead(mock_data.c_str()),
1096 StaticSocketDataProvider data_socket1;
1097 StaticSocketDataProvider data_socket2(data_reads, arraysize(data_reads),
1098 NULL, 0);
1099 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
1100 mock_socket_factory_.AddSocketDataProvider(&data_socket1);
1101 mock_socket_factory_.AddSocketDataProvider(&data_socket2);
1102 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1104 // Start the transaction.
1105 ASSERT_EQ(ERR_IO_PENDING,
1106 transaction_.Start(&request_info, callback_.callback(),
1107 BoundNetLog()));
1108 ASSERT_EQ(OK, callback_.WaitForResult());
1110 // The transaction fires the callback when we can start reading data. That
1111 // means that the data socket should be open.
1112 MockTCPClientSocket* data_socket =
1113 static_cast<MockTCPClientSocket*>(transaction_.data_socket_.get());
1114 ASSERT_TRUE(data_socket);
1115 ASSERT_TRUE(data_socket->IsConnected());
1117 // Even if the PASV response specified some other address, we connect
1118 // to the address we used for control connection (which could be 127.0.0.1
1119 // or ::1 depending on whether we use IPv6).
1120 for (AddressList::const_iterator it = data_socket->addresses().begin();
1121 it != data_socket->addresses().end(); ++it) {
1122 EXPECT_NE("10.1.2.3", it->ToStringWithoutPort());
1126 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat1) {
1127 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1128 if (GetFamily() == AF_INET)
1129 return;
1131 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n",
1132 FtpSocketDataProvider::PRE_QUIT);
1133 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1136 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat2) {
1137 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1138 if (GetFamily() == AF_INET)
1139 return;
1141 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n",
1142 FtpSocketDataProvider::PRE_QUIT);
1143 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1146 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat3) {
1147 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1148 if (GetFamily() == AF_INET)
1149 return;
1151 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n",
1152 FtpSocketDataProvider::PRE_QUIT);
1153 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1156 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat4) {
1157 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1158 if (GetFamily() == AF_INET)
1159 return;
1161 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n",
1162 FtpSocketDataProvider::PRE_QUIT);
1163 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1166 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvReallyBadFormat5) {
1167 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1168 if (GetFamily() == AF_INET)
1169 return;
1171 // Breaking the string in the next line prevents MSVC warning C4125.
1172 const char response[] = "227 Portscan (\0\0\031" "773\0)\r\n";
1173 FtpSocketDataProviderEvilEpsv ctrl_socket(response, sizeof(response)-1,
1174 FtpSocketDataProvider::PRE_QUIT);
1175 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1178 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort1) {
1179 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1180 if (GetFamily() == AF_INET)
1181 return;
1183 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n",
1184 FtpSocketDataProvider::PRE_QUIT);
1185 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1188 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort2) {
1189 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1190 if (GetFamily() == AF_INET)
1191 return;
1193 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n",
1194 FtpSocketDataProvider::PRE_QUIT);
1195 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1198 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort3) {
1199 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1200 if (GetFamily() == AF_INET)
1201 return;
1203 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n",
1204 FtpSocketDataProvider::PRE_QUIT);
1205 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1208 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvUnsafePort4) {
1209 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1210 if (GetFamily() == AF_INET)
1211 return;
1213 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n",
1214 FtpSocketDataProvider::PRE_QUIT);
1215 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1218 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvWeirdSep) {
1219 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1220 if (GetFamily() == AF_INET)
1221 return;
1223 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n",
1224 FtpSocketDataProvider::PRE_RETR);
1225 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1228 TEST_P(FtpNetworkTransactionTest,
1229 DownloadTransactionEvilEpsvWeirdSepUnsafePort) {
1230 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1231 if (GetFamily() == AF_INET)
1232 return;
1234 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n",
1235 FtpSocketDataProvider::PRE_QUIT);
1236 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
1239 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilEpsvIllegalHost) {
1240 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1241 if (GetFamily() == AF_INET)
1242 return;
1244 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|2|::1|31744|)\r\n",
1245 FtpSocketDataProvider::PRE_QUIT);
1246 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1249 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
1250 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
1251 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
1254 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
1255 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
1256 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
1259 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
1260 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
1261 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
1264 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
1265 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
1266 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
1269 TEST_P(FtpNetworkTransactionTest, EvilRestartUser) {
1270 FtpSocketDataProvider ctrl_socket1;
1271 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1272 FtpSocketDataProvider::PRE_QUIT,
1273 "530 Login authentication failed\r\n");
1274 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1276 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1278 ASSERT_EQ(ERR_IO_PENDING,
1279 transaction_.Start(&request_info, callback_.callback(),
1280 BoundNetLog()));
1281 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1283 MockRead ctrl_reads[] = {
1284 MockRead("220 host TestFTPd\r\n"),
1285 MockRead("221 Goodbye!\r\n"),
1286 MockRead(SYNCHRONOUS, OK),
1288 MockWrite ctrl_writes[] = {
1289 MockWrite("QUIT\r\n"),
1291 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1292 ctrl_writes, arraysize(ctrl_writes));
1293 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1294 ASSERT_EQ(ERR_IO_PENDING,
1295 transaction_.RestartWithAuth(
1296 AuthCredentials(
1297 base::ASCIIToUTF16("foo\nownz0red"),
1298 base::ASCIIToUTF16("innocent")),
1299 callback_.callback()));
1300 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1303 TEST_P(FtpNetworkTransactionTest, EvilRestartPassword) {
1304 FtpSocketDataProvider ctrl_socket1;
1305 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
1306 FtpSocketDataProvider::PRE_QUIT,
1307 "530 Login authentication failed\r\n");
1308 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
1310 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
1312 ASSERT_EQ(ERR_IO_PENDING,
1313 transaction_.Start(&request_info, callback_.callback(),
1314 BoundNetLog()));
1315 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult());
1317 MockRead ctrl_reads[] = {
1318 MockRead("220 host TestFTPd\r\n"),
1319 MockRead("331 User okay, send password\r\n"),
1320 MockRead("221 Goodbye!\r\n"),
1321 MockRead(SYNCHRONOUS, OK),
1323 MockWrite ctrl_writes[] = {
1324 MockWrite("USER innocent\r\n"),
1325 MockWrite("QUIT\r\n"),
1327 StaticSocketDataProvider ctrl_socket2(ctrl_reads, arraysize(ctrl_reads),
1328 ctrl_writes, arraysize(ctrl_writes));
1329 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
1330 ASSERT_EQ(ERR_IO_PENDING,
1331 transaction_.RestartWithAuth(
1332 AuthCredentials(base::ASCIIToUTF16("innocent"),
1333 base::ASCIIToUTF16("foo\nownz0red")),
1334 callback_.callback()));
1335 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
1338 TEST_P(FtpNetworkTransactionTest, Escaping) {
1339 FtpSocketDataProviderEscaping ctrl_socket;
1340 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
1341 OK);
1344 // Test for http://crbug.com/23794.
1345 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilSize) {
1346 // Try to overflow int64 in the response.
1347 FtpSocketDataProviderEvilSize ctrl_socket(
1348 "213 99999999999999999999999999999999\r\n",
1349 FtpSocketDataProvider::PRE_QUIT);
1350 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
1353 // Test for http://crbug.com/36360.
1354 TEST_P(FtpNetworkTransactionTest, DownloadTransactionBigSize) {
1355 // Pass a valid, but large file size. The transaction should not fail.
1356 FtpSocketDataProviderEvilSize ctrl_socket(
1357 "213 3204427776\r\n",
1358 FtpSocketDataProvider::PRE_CWD);
1359 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
1360 EXPECT_EQ(3204427776LL,
1361 transaction_.GetResponseInfo()->expected_content_size);
1364 // Regression test for http://crbug.com/25023.
1365 TEST_P(FtpNetworkTransactionTest, CloseConnection) {
1366 FtpSocketDataProviderCloseConnection ctrl_socket;
1367 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
1370 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
1371 FtpSocketDataProviderDirectoryListing ctrl_socket;
1372 // Use unallocated 599 FTP error code to make sure it falls into the generic
1373 // ERR_FTP_FAILED bucket.
1374 TransactionFailHelper(&ctrl_socket,
1375 "ftp://host",
1376 FtpSocketDataProvider::PRE_USER,
1377 FtpSocketDataProvider::PRE_QUIT,
1378 "599 fail\r\n",
1379 ERR_FTP_FAILED);
1382 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
1383 FtpSocketDataProviderDirectoryListing ctrl_socket;
1384 TransactionFailHelper(&ctrl_socket,
1385 "ftp://host",
1386 FtpSocketDataProvider::PRE_PASSWD,
1387 FtpSocketDataProvider::PRE_QUIT,
1388 "530 Login authentication failed\r\n",
1389 ERR_FTP_FAILED);
1392 // Regression test for http://crbug.com/38707.
1393 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPass503) {
1394 FtpSocketDataProviderDirectoryListing ctrl_socket;
1395 TransactionFailHelper(&ctrl_socket,
1396 "ftp://host",
1397 FtpSocketDataProvider::PRE_PASSWD,
1398 FtpSocketDataProvider::PRE_QUIT,
1399 "503 Bad sequence of commands\r\n",
1400 ERR_FTP_BAD_COMMAND_SEQUENCE);
1403 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
1404 FtpSocketDataProviderDirectoryListing ctrl_socket;
1405 // Use unallocated 599 FTP error code to make sure it falls into the generic
1406 // ERR_FTP_FAILED bucket.
1407 TransactionFailHelper(&ctrl_socket,
1408 "ftp://host",
1409 FtpSocketDataProvider::PRE_SYST,
1410 FtpSocketDataProvider::PRE_PWD,
1411 "599 fail\r\n",
1412 OK);
1415 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
1416 FtpSocketDataProviderDirectoryListing ctrl_socket;
1417 // Use unallocated 599 FTP error code to make sure it falls into the generic
1418 // ERR_FTP_FAILED bucket.
1419 TransactionFailHelper(&ctrl_socket,
1420 "ftp://host",
1421 FtpSocketDataProvider::PRE_PWD,
1422 FtpSocketDataProvider::PRE_QUIT,
1423 "599 fail\r\n",
1424 ERR_FTP_FAILED);
1427 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
1428 FtpSocketDataProviderDirectoryListing ctrl_socket;
1429 // Use unallocated 599 FTP error code to make sure it falls into the generic
1430 // ERR_FTP_FAILED bucket.
1431 TransactionFailHelper(&ctrl_socket,
1432 "ftp://host",
1433 FtpSocketDataProvider::PRE_TYPE,
1434 FtpSocketDataProvider::PRE_QUIT,
1435 "599 fail\r\n",
1436 ERR_FTP_FAILED);
1439 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailEpsv) {
1440 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1441 if (GetFamily() == AF_INET)
1442 return;
1444 FtpSocketDataProviderDirectoryListing ctrl_socket;
1445 // Use unallocated 599 FTP error code to make sure it falls into the generic
1446 // ERR_FTP_FAILED bucket.
1447 TransactionFailHelper(
1448 &ctrl_socket, "ftp://host", FtpSocketDataProvider::PRE_LIST_EPSV,
1449 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1452 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1453 FtpSocketDataProviderDirectoryListing ctrl_socket;
1454 // Use unallocated 599 FTP error code to make sure it falls into the generic
1455 // ERR_FTP_FAILED bucket.
1456 TransactionFailHelper(&ctrl_socket,
1457 "ftp://host",
1458 FtpSocketDataProvider::PRE_CWD,
1459 FtpSocketDataProvider::PRE_QUIT,
1460 "599 fail\r\n",
1461 ERR_FTP_FAILED);
1464 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1465 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1466 // Use unallocated 599 FTP error code to make sure it falls into the generic
1467 // ERR_FTP_FAILED bucket.
1468 TransactionFailHelper(&ctrl_socket,
1469 "ftp://host/dir",
1470 FtpSocketDataProvider::PRE_LIST,
1471 FtpSocketDataProvider::PRE_QUIT,
1472 "599 fail\r\n",
1473 ERR_FTP_FAILED);
1476 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1477 FtpSocketDataProviderFileDownload ctrl_socket;
1478 // Use unallocated 599 FTP error code to make sure it falls into the generic
1479 // ERR_FTP_FAILED bucket.
1480 TransactionFailHelper(&ctrl_socket,
1481 "ftp://host/file",
1482 FtpSocketDataProvider::PRE_USER,
1483 FtpSocketDataProvider::PRE_QUIT,
1484 "599 fail\r\n",
1485 ERR_FTP_FAILED);
1488 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1489 FtpSocketDataProviderFileDownload ctrl_socket;
1490 TransactionFailHelper(&ctrl_socket,
1491 "ftp://host/file",
1492 FtpSocketDataProvider::PRE_PASSWD,
1493 FtpSocketDataProvider::PRE_QUIT,
1494 "530 Login authentication failed\r\n",
1495 ERR_FTP_FAILED);
1498 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1499 FtpSocketDataProviderFileDownload ctrl_socket;
1500 // Use unallocated 599 FTP error code to make sure it falls into the generic
1501 // ERR_FTP_FAILED bucket.
1502 TransactionFailHelper(&ctrl_socket,
1503 "ftp://host/file",
1504 FtpSocketDataProvider::PRE_SYST,
1505 FtpSocketDataProvider::PRE_PWD,
1506 "599 fail\r\n",
1507 OK);
1510 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1511 FtpSocketDataProviderFileDownload ctrl_socket;
1512 // Use unallocated 599 FTP error code to make sure it falls into the generic
1513 // ERR_FTP_FAILED bucket.
1514 TransactionFailHelper(&ctrl_socket,
1515 "ftp://host/file",
1516 FtpSocketDataProvider::PRE_PWD,
1517 FtpSocketDataProvider::PRE_QUIT,
1518 "599 fail\r\n",
1519 ERR_FTP_FAILED);
1522 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1523 FtpSocketDataProviderFileDownload ctrl_socket;
1524 // Use unallocated 599 FTP error code to make sure it falls into the generic
1525 // ERR_FTP_FAILED bucket.
1526 TransactionFailHelper(&ctrl_socket,
1527 "ftp://host/file",
1528 FtpSocketDataProvider::PRE_TYPE,
1529 FtpSocketDataProvider::PRE_QUIT,
1530 "599 fail\r\n",
1531 ERR_FTP_FAILED);
1534 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailEpsv) {
1535 // This test makes no sense for IPv4 connections (we don't use EPSV there).
1536 if (GetFamily() == AF_INET)
1537 return;
1539 FtpSocketDataProviderFileDownload ctrl_socket;
1540 // Use unallocated 599 FTP error code to make sure it falls into the generic
1541 // ERR_FTP_FAILED bucket.
1542 TransactionFailHelper(
1543 &ctrl_socket, "ftp://host/file", FtpSocketDataProvider::PRE_RETR_EPSV,
1544 FtpSocketDataProvider::PRE_NOPASV, "599 fail\r\n", ERR_FTP_FAILED);
1547 TEST_P(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1548 FtpSocketDataProviderFileDownload ctrl_socket;
1549 // Use unallocated 599 FTP error code to make sure it falls into the generic
1550 // ERR_FTP_FAILED bucket.
1551 TransactionFailHelper(&ctrl_socket,
1552 "ftp://host/file",
1553 FtpSocketDataProvider::PRE_RETR,
1554 FtpSocketDataProvider::PRE_QUIT,
1555 "599 fail\r\n",
1556 ERR_FTP_FAILED);
1559 TEST_P(FtpNetworkTransactionTest, FileNotFound) {
1560 FtpSocketDataProviderFileNotFound ctrl_socket;
1561 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED);
1564 // Test for http://crbug.com/38845.
1565 TEST_P(FtpNetworkTransactionTest, ZeroLengthDirInPWD) {
1566 FtpSocketDataProviderFileDownload ctrl_socket;
1567 TransactionFailHelper(&ctrl_socket,
1568 "ftp://host/file",
1569 FtpSocketDataProvider::PRE_PWD,
1570 FtpSocketDataProvider::PRE_TYPE,
1571 "257 \"\"\r\n",
1572 OK);
1575 INSTANTIATE_TEST_CASE_P(FTP,
1576 FtpNetworkTransactionTest,
1577 ::testing::Values(AF_INET, AF_INET6));
1579 } // namespace net