1 // Copyright (c) 2009 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.
4
5 #include "net/ftp/ftp_network_transaction.h"
6
7 #include "build/build_config.h"
8
9 #include "base/ref_counted.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/mock_host_resolver.h"
12 #include "net/base/net_util.h"
13 #include "net/base/sys_addrinfo.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/ftp/ftp_network_session.h"
16 #include "net/ftp/ftp_request_info.h"
17 #include "net/socket/socket_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/platform_test.h"
20
21 namespace {
22
23 // Size we use for IOBuffers used to receive data from the test data socket.
24 const int kBufferSize = 128;
25
26 } // namespace
27
28 namespace net {
29
30 class FtpSocketDataProvider : public DynamicSocketDataProvider {
31 public:
32 enum State {
33 NONE,
34 PRE_USER,
35 PRE_PASSWD,
36 PRE_SYST,
37 PRE_PWD,
38 PRE_TYPE,
39 PRE_PASV,
40 PRE_SIZE,
41 PRE_MDTM,
42 PRE_MLSD,
43 PRE_LIST,
44 PRE_RETR,
45 PRE_PASV2,
46 PRE_CWD,
47 PRE_QUIT,
48 QUIT
49 };
50
FtpSocketDataProvider()51 FtpSocketDataProvider()
52 : failure_injection_state_(NONE),
53 multiline_welcome_(false) {
54 Init();
55 }
56
OnWrite(const std::string & data)57 virtual MockWriteResult OnWrite(const std::string& data) {
58 if (InjectFault())
59 return MockWriteResult(true, data.length());
60 switch (state()) {
61 case PRE_USER:
62 return Verify("USER anonymous\r\n", data, PRE_PASSWD,
63 "331 Password needed\r\n");
64 case PRE_PASSWD:
65 {
66 const char* response_one = "230 Welcome\r\n";
67 const char* response_multi = "230- One\r\n230- Two\r\n230 Three\r\n";
68 return Verify("PASS chrome@example.com\r\n", data, PRE_SYST,
69 multiline_welcome_ ? response_multi : response_one);
70 }
71 case PRE_SYST:
72 return Verify("SYST\r\n", data, PRE_PWD, "215 UNIX\r\n");
73 case PRE_PWD:
74 return Verify("PWD\r\n", data, PRE_TYPE,
75 "257 \"/\" is your current location\r\n");
76 case PRE_TYPE:
77 return Verify("TYPE I\r\n", data, PRE_PASV,
78 "200 TYPE is now 8-bit binary\r\n");
79 case PRE_PASV:
80 return Verify("PASV\r\n", data, PRE_SIZE,
81 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
82 case PRE_PASV2:
83 // Parser should also accept format without parentheses.
84 return Verify("PASV\r\n", data, PRE_CWD,
85 "227 Entering Passive Mode 127,0,0,1,123,456\r\n");
86 case PRE_QUIT:
87 return Verify("QUIT\r\n", data, QUIT, "221 Goodbye.\r\n");
88 default:
89 NOTREACHED() << "State not handled " << state();
90 return MockWriteResult(true, ERR_UNEXPECTED);
91 }
92 }
93
InjectFailure(State state,State next_state,const char * response)94 void InjectFailure(State state, State next_state, const char* response) {
95 DCHECK_EQ(NONE, failure_injection_state_);
96 DCHECK_NE(NONE, state);
97 DCHECK_NE(NONE, next_state);
98 DCHECK_NE(state, next_state);
99 failure_injection_state_ = state;
100 failure_injection_next_state_ = next_state;
101 fault_response_ = response;
102 }
103
state() const104 State state() const {
105 return state_;
106 }
107
Reset()108 virtual void Reset() {
109 DynamicSocketDataProvider::Reset();
110 Init();
111 }
112
set_multiline_welcome(bool multiline)113 void set_multiline_welcome(bool multiline) {
114 multiline_welcome_ = multiline;
115 }
116
117 protected:
Init()118 void Init() {
119 state_ = PRE_USER;
120 SimulateRead("220 host TestFTPd\r\n");
121 }
122
123 // If protocol fault injection has been requested, adjusts state and mocked
124 // read and returns true.
InjectFault()125 bool InjectFault() {
126 if (state_ != failure_injection_state_)
127 return false;
128 SimulateRead(fault_response_);
129 state_ = failure_injection_next_state_;
130 return true;
131 }
132
Verify(const std::string & expected,const std::string & data,State next_state,const char * next_read)133 MockWriteResult Verify(const std::string& expected,
134 const std::string& data,
135 State next_state,
136 const char* next_read) {
137 EXPECT_EQ(expected, data);
138 if (expected == data) {
139 state_ = next_state;
140 SimulateRead(next_read);
141 return MockWriteResult(true, data.length());
142 }
143 return MockWriteResult(true, ERR_UNEXPECTED);
144 }
145
146 private:
147 State state_;
148 State failure_injection_state_;
149 State failure_injection_next_state_;
150 const char* fault_response_;
151
152 // If true, we will send multiple 230 lines as response after PASS.
153 bool multiline_welcome_;
154
155 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider);
156 };
157
158 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider {
159 public:
FtpSocketDataProviderDirectoryListing()160 FtpSocketDataProviderDirectoryListing() {
161 }
162
OnWrite(const std::string & data)163 virtual MockWriteResult OnWrite(const std::string& data) {
164 if (InjectFault())
165 return MockWriteResult(true, data.length());
166 switch (state()) {
167 case PRE_SIZE:
168 return Verify("SIZE /\r\n", data, PRE_MDTM,
169 "550 I can only retrieve regular files\r\n");
170 case PRE_MDTM:
171 return Verify("MDTM /\r\n", data, PRE_RETR,
172 "213 20070221112533\r\n");
173 case PRE_RETR:
174 return Verify("RETR /\r\n", data, PRE_PASV2,
175 "550 Can't download directory\r\n");
176
177 case PRE_CWD:
178 return Verify("CWD /\r\n", data, PRE_MLSD, "200 OK\r\n");
179 case PRE_MLSD:
180 return Verify("MLSD\r\n", data, PRE_QUIT,
181 "150 Accepted data connection\r\n"
182 "226 MLSD complete\r\n");
183 case PRE_LIST:
184 return Verify("LIST\r\n", data, PRE_QUIT, "200 OK\r\n");
185 default:
186 return FtpSocketDataProvider::OnWrite(data);
187 }
188 }
189
190 private:
191 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing);
192 };
193
194 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider {
195 public:
FtpSocketDataProviderVMSDirectoryListing()196 FtpSocketDataProviderVMSDirectoryListing() {
197 }
198
OnWrite(const std::string & data)199 virtual MockWriteResult OnWrite(const std::string& data) {
200 if (InjectFault())
201 return MockWriteResult(true, data.length());
202 switch (state()) {
203 case PRE_SYST:
204 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
205 case PRE_PWD:
206 return Verify("PWD\r\n", data, PRE_TYPE,
207 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
208 case PRE_SIZE:
209 return Verify("SIZE ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_MDTM,
210 "550 I can only retrieve regular files\r\n");
211 case PRE_MDTM:
212 return Verify("MDTM ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_RETR,
213 "213 20070221112533\r\n");
214 case PRE_RETR:
215 return Verify("RETR ANONYMOUS_ROOT:[000000]dir\r\n", data, PRE_PASV2,
216 "550 Can't download directory\r\n");
217 case PRE_CWD:
218 return Verify("CWD ANONYMOUS_ROOT:[dir]\r\n", data, PRE_MLSD,
219 "200 OK\r\n");
220 case PRE_MLSD:
221 return Verify("MLSD\r\n", data, PRE_LIST, "500 Invalid command\r\n");
222 case PRE_LIST:
223 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
224 default:
225 return FtpSocketDataProvider::OnWrite(data);
226 }
227 }
228
229 private:
230 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing);
231 };
232
233 class FtpSocketDataProviderVMSDirectoryListingRootDirectory
234 : public FtpSocketDataProvider {
235 public:
FtpSocketDataProviderVMSDirectoryListingRootDirectory()236 FtpSocketDataProviderVMSDirectoryListingRootDirectory() {
237 }
238
OnWrite(const std::string & data)239 virtual MockWriteResult OnWrite(const std::string& data) {
240 if (InjectFault())
241 return MockWriteResult(true, data.length());
242 switch (state()) {
243 case PRE_SYST:
244 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
245 case PRE_PWD:
246 return Verify("PWD\r\n", data, PRE_TYPE,
247 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
248 case PRE_SIZE:
249 return Verify("SIZE ANONYMOUS_ROOT\r\n", data, PRE_MDTM,
250 "550 I can only retrieve regular files\r\n");
251 case PRE_MDTM:
252 return Verify("MDTM ANONYMOUS_ROOT\r\n", data, PRE_RETR,
253 "213 20070221112533\r\n");
254 case PRE_RETR:
255 return Verify("RETR ANONYMOUS_ROOT\r\n", data, PRE_PASV2,
256 "550 Can't download directory\r\n");
257 case PRE_CWD:
258 return Verify("CWD ANONYMOUS_ROOT:[000000]\r\n", data, PRE_MLSD,
259 "200 OK\r\n");
260 case PRE_MLSD:
261 return Verify("MLSD\r\n", data, PRE_LIST, "500 Invalid command\r\n");
262 case PRE_LIST:
263 return Verify("LIST *.*;0\r\n", data, PRE_QUIT, "200 OK\r\n");
264 default:
265 return FtpSocketDataProvider::OnWrite(data);
266 }
267 }
268
269 private:
270 DISALLOW_COPY_AND_ASSIGN(
271 FtpSocketDataProviderVMSDirectoryListingRootDirectory);
272 };
273
274 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider {
275 public:
FtpSocketDataProviderFileDownload()276 FtpSocketDataProviderFileDownload() {
277 }
278
OnWrite(const std::string & data)279 virtual MockWriteResult OnWrite(const std::string& data) {
280 if (InjectFault())
281 return MockWriteResult(true, data.length());
282 switch (state()) {
283 case PRE_SIZE:
284 return Verify("SIZE /file\r\n", data, PRE_MDTM,
285 "213 18\r\n");
286 case PRE_MDTM:
287 return Verify("MDTM /file\r\n", data, PRE_RETR,
288 "213 20070221112533\r\n");
289 case PRE_RETR:
290 return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n");
291 default:
292 return FtpSocketDataProvider::OnWrite(data);
293 }
294 }
295
296 private:
297 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload);
298 };
299
300 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider {
301 public:
FtpSocketDataProviderVMSFileDownload()302 FtpSocketDataProviderVMSFileDownload() {
303 }
304
OnWrite(const std::string & data)305 virtual MockWriteResult OnWrite(const std::string& data) {
306 if (InjectFault())
307 return MockWriteResult(true, data.length());
308 switch (state()) {
309 case PRE_SYST:
310 return Verify("SYST\r\n", data, PRE_PWD, "215 VMS\r\n");
311 case PRE_PWD:
312 return Verify("PWD\r\n", data, PRE_TYPE,
313 "257 \"ANONYMOUS_ROOT:[000000]\"\r\n");
314 case PRE_SIZE:
315 return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_MDTM,
316 "213 18\r\n");
317 case PRE_MDTM:
318 return Verify("MDTM ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_RETR,
319 "213 20070221112533\r\n");
320 case PRE_RETR:
321 return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT,
322 "200 OK\r\n");
323 default:
324 return FtpSocketDataProvider::OnWrite(data);
325 }
326 }
327
328 private:
329 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload);
330 };
331
332 class FtpSocketDataProviderEscaping : public FtpSocketDataProvider {
333 public:
FtpSocketDataProviderEscaping()334 FtpSocketDataProviderEscaping() {
335 }
336
OnWrite(const std::string & data)337 virtual MockWriteResult OnWrite(const std::string& data) {
338 if (InjectFault())
339 return MockWriteResult(true, data.length());
340 switch (state()) {
341 case PRE_SIZE:
342 return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_MDTM,
343 "213 18\r\n");
344 case PRE_MDTM:
345 return Verify("MDTM / !\"#$%y\200\201\r\n", data, PRE_RETR,
346 "213 20070221112533\r\n");
347 case PRE_RETR:
348 return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT,
349 "200 OK\r\n");
350 default:
351 return FtpSocketDataProvider::OnWrite(data);
352 }
353 }
354
355 private:
356 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping);
357 };
358
359 class FtpSocketDataProviderFileDownloadAcceptedDataConnection
360 : public FtpSocketDataProviderFileDownload {
361 public:
FtpSocketDataProviderFileDownloadAcceptedDataConnection()362 FtpSocketDataProviderFileDownloadAcceptedDataConnection() {
363 }
364
OnWrite(const std::string & data)365 virtual MockWriteResult OnWrite(const std::string& data) {
366 if (InjectFault())
367 return MockWriteResult(true, data.length());
368 switch (state()) {
369 case PRE_RETR:
370 return Verify("RETR /file\r\n", data, PRE_QUIT,
371 "150 Accepted Data Connection\r\n");
372 default:
373 return FtpSocketDataProviderFileDownload::OnWrite(data);
374 }
375 }
376
377 private:
378 DISALLOW_COPY_AND_ASSIGN(
379 FtpSocketDataProviderFileDownloadAcceptedDataConnection);
380 };
381
382 class FtpSocketDataProviderFileDownloadTransferStarting
383 : public FtpSocketDataProviderFileDownload {
384 public:
FtpSocketDataProviderFileDownloadTransferStarting()385 FtpSocketDataProviderFileDownloadTransferStarting() {
386 }
387
OnWrite(const std::string & data)388 virtual MockWriteResult OnWrite(const std::string& data) {
389 if (InjectFault())
390 return MockWriteResult(true, data.length());
391 switch (state()) {
392 case PRE_RETR:
393 return Verify("RETR /file\r\n", data, PRE_QUIT,
394 "125-Data connection already open.\r\n"
395 "125 Transfer starting.\r\n"
396 "226 Transfer complete.\r\n");
397 default:
398 return FtpSocketDataProviderFileDownload::OnWrite(data);
399 }
400 }
401
402 private:
403 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting);
404 };
405
406 class FtpSocketDataProviderDirectoryListingTransferStarting
407 : public FtpSocketDataProviderDirectoryListing {
408 public:
FtpSocketDataProviderDirectoryListingTransferStarting()409 FtpSocketDataProviderDirectoryListingTransferStarting() {
410 }
411
OnWrite(const std::string & data)412 virtual MockWriteResult OnWrite(const std::string& data) {
413 if (InjectFault())
414 return MockWriteResult(true, data.length());
415 switch (state()) {
416 case PRE_LIST:
417 return Verify("LIST\r\n", data, PRE_QUIT,
418 "125-Data connection already open.\r\n"
419 "125 Transfer starting.\r\n"
420 "226 Transfer complete.\r\n");
421 default:
422 return FtpSocketDataProviderDirectoryListing::OnWrite(data);
423 }
424 }
425
426 private:
427 DISALLOW_COPY_AND_ASSIGN(
428 FtpSocketDataProviderDirectoryListingTransferStarting);
429 };
430
431 class FtpSocketDataProviderFileDownloadInvalidResponse
432 : public FtpSocketDataProviderFileDownload {
433 public:
FtpSocketDataProviderFileDownloadInvalidResponse()434 FtpSocketDataProviderFileDownloadInvalidResponse() {
435 }
436
OnWrite(const std::string & data)437 virtual MockWriteResult OnWrite(const std::string& data) {
438 if (InjectFault())
439 return MockWriteResult(true, data.length());
440 switch (state()) {
441 case PRE_SIZE:
442 return Verify("SIZE /file\r\n", data, PRE_QUIT,
443 "500 Evil Response\r\n"
444 "500 More Evil\r\n");
445 default:
446 return FtpSocketDataProviderFileDownload::OnWrite(data);
447 }
448 }
449
450 private:
451 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse);
452 };
453
454 class FtpSocketDataProviderFileDownloadRetrFail
455 : public FtpSocketDataProviderFileDownload {
456 public:
FtpSocketDataProviderFileDownloadRetrFail()457 FtpSocketDataProviderFileDownloadRetrFail() {
458 }
459
OnWrite(const std::string & data)460 virtual MockWriteResult OnWrite(const std::string& data) {
461 if (InjectFault())
462 return MockWriteResult(true, data.length());
463 switch (state()) {
464 case PRE_CWD:
465 return Verify("CWD /file\r\n", data, PRE_QUIT,
466 "550 file is a directory\r\n");
467 default:
468 return FtpSocketDataProviderFileDownload::OnWrite(data);
469 }
470 }
471
472 private:
473 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadRetrFail);
474 };
475
476 class FtpSocketDataProviderEvilPasv : public FtpSocketDataProviderFileDownload {
477 public:
FtpSocketDataProviderEvilPasv(const char * pasv_response,State expected_state)478 explicit FtpSocketDataProviderEvilPasv(const char* pasv_response,
479 State expected_state)
480 : pasv_response_(pasv_response),
481 expected_state_(expected_state) {
482 }
483
OnWrite(const std::string & data)484 virtual MockWriteResult OnWrite(const std::string& data) {
485 if (InjectFault())
486 return MockWriteResult(true, data.length());
487 switch (state()) {
488 case PRE_PASV:
489 return Verify("PASV\r\n", data, expected_state_, pasv_response_);
490 default:
491 return FtpSocketDataProviderFileDownload::OnWrite(data);
492 }
493 }
494
495 private:
496 const char* pasv_response_;
497 const State expected_state_;
498
499 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv);
500 };
501
502 class FtpSocketDataProviderEvilLogin : public FtpSocketDataProviderFileDownload {
503 public:
FtpSocketDataProviderEvilLogin(const char * expected_user,const char * expected_password)504 FtpSocketDataProviderEvilLogin(const char* expected_user,
505 const char* expected_password)
506 : expected_user_(expected_user),
507 expected_password_(expected_password) {
508 }
509
OnWrite(const std::string & data)510 virtual MockWriteResult OnWrite(const std::string& data) {
511 if (InjectFault())
512 return MockWriteResult(true, data.length());
513 switch (state()) {
514 case PRE_USER:
515 return Verify(std::string("USER ") + expected_user_ + "\r\n", data,
516 PRE_PASSWD, "331 Password needed\r\n");
517 case PRE_PASSWD:
518 return Verify(std::string("PASS ") + expected_password_ + "\r\n", data,
519 PRE_SYST, "230 Welcome\r\n");
520 default:
521 return FtpSocketDataProviderFileDownload::OnWrite(data);
522 }
523 }
524
525 private:
526 const char* expected_user_;
527 const char* expected_password_;
528
529 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin);
530 };
531
532 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider {
533 public:
FtpSocketDataProviderCloseConnection()534 FtpSocketDataProviderCloseConnection() {
535 }
536
OnWrite(const std::string & data)537 virtual MockWriteResult OnWrite(const std::string& data) {
538 if (InjectFault())
539 return MockWriteResult(true, data.length());
540 switch (state()) {
541 case PRE_USER:
542 return Verify("USER anonymous\r\n", data,
543 PRE_QUIT, "");
544 default:
545 return FtpSocketDataProvider::OnWrite(data);
546 }
547 }
548
549 private:
550 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection);
551 };
552
553 class FtpNetworkTransactionTest : public PlatformTest {
554 public:
FtpNetworkTransactionTest()555 FtpNetworkTransactionTest()
556 : host_resolver_(new MockHostResolver),
557 session_(new FtpNetworkSession(host_resolver_)),
558 transaction_(session_.get(), &mock_socket_factory_) {
559 }
560
561 protected:
GetRequestInfo(const std::string & url)562 FtpRequestInfo GetRequestInfo(const std::string& url) {
563 FtpRequestInfo info;
564 info.url = GURL(url);
565 return info;
566 }
567
ExecuteTransaction(FtpSocketDataProvider * ctrl_socket,const char * request,int expected_result)568 void ExecuteTransaction(FtpSocketDataProvider* ctrl_socket,
569 const char* request,
570 int expected_result) {
571 std::string mock_data("mock-data");
572 MockRead data_reads[] = {
573 MockRead(mock_data.c_str()),
574 };
575 // For compatibility with FileZilla, the transaction code will use two data
576 // sockets for directory requests. For more info see http://crbug.com/25316.
577 StaticSocketDataProvider data1(data_reads, NULL);
578 StaticSocketDataProvider data2(data_reads, NULL);
579 mock_socket_factory_.AddSocketDataProvider(ctrl_socket);
580 mock_socket_factory_.AddSocketDataProvider(&data1);
581 mock_socket_factory_.AddSocketDataProvider(&data2);
582 FtpRequestInfo request_info = GetRequestInfo(request);
583 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
584 ASSERT_EQ(ERR_IO_PENDING,
585 transaction_.Start(&request_info, &callback_, NULL));
586 EXPECT_NE(LOAD_STATE_IDLE, transaction_.GetLoadState());
587 EXPECT_EQ(expected_result, callback_.WaitForResult());
588 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state());
589 if (expected_result == OK) {
590 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
591 memset(io_buffer->data(), 0, kBufferSize);
592 ASSERT_EQ(ERR_IO_PENDING,
593 transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
594 EXPECT_EQ(static_cast<int>(mock_data.length()),
595 callback_.WaitForResult());
596 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
597 }
598 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
599 }
600
TransactionFailHelper(FtpSocketDataProvider * ctrl_socket,const char * request,FtpSocketDataProvider::State state,FtpSocketDataProvider::State next_state,const char * response,int expected_result)601 void TransactionFailHelper(FtpSocketDataProvider* ctrl_socket,
602 const char* request,
603 FtpSocketDataProvider::State state,
604 FtpSocketDataProvider::State next_state,
605 const char* response,
606 int expected_result) {
607 ctrl_socket->InjectFailure(state, next_state, response);
608 ExecuteTransaction(ctrl_socket, request, expected_result);
609 }
610
611 scoped_refptr<MockHostResolver> host_resolver_;
612 scoped_refptr<FtpNetworkSession> session_;
613 MockClientSocketFactory mock_socket_factory_;
614 FtpNetworkTransaction transaction_;
615 TestCompletionCallback callback_;
616 };
617
TEST_F(FtpNetworkTransactionTest,FailedLookup)618 TEST_F(FtpNetworkTransactionTest, FailedLookup) {
619 FtpRequestInfo request_info = GetRequestInfo("ftp://badhost");
620 host_resolver_->rules()->AddSimulatedFailure("badhost");
621 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
622 ASSERT_EQ(ERR_IO_PENDING,
623 transaction_.Start(&request_info, &callback_, NULL));
624 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
625 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
626 }
627
TEST_F(FtpNetworkTransactionTest,DirectoryTransaction)628 TEST_F(FtpNetworkTransactionTest, DirectoryTransaction) {
629 FtpSocketDataProviderDirectoryListing ctrl_socket;
630 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
631 }
632
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcome)633 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) {
634 FtpSocketDataProviderDirectoryListing ctrl_socket;
635 ctrl_socket.set_multiline_welcome(true);
636 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
637 }
638
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionShortReads2)639 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) {
640 FtpSocketDataProviderDirectoryListing ctrl_socket;
641 ctrl_socket.set_short_read_limit(2);
642 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
643 }
644
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionShortReads5)645 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) {
646 FtpSocketDataProviderDirectoryListing ctrl_socket;
647 ctrl_socket.set_short_read_limit(5);
648 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
649 }
650
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMultilineWelcomeShort)651 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcomeShort) {
652 FtpSocketDataProviderDirectoryListing ctrl_socket;
653 // The client will not consume all three 230 lines. That's good, we want to
654 // test that scenario.
655 ctrl_socket.allow_unconsumed_reads(true);
656 ctrl_socket.set_multiline_welcome(true);
657 ctrl_socket.set_short_read_limit(5);
658 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
659 }
660
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionVMS)661 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMS) {
662 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
663 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK);
664 }
665
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionVMSRootDirectory)666 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) {
667 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket;
668 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
669 }
670
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionTransferStarting)671 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) {
672 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket;
673 ExecuteTransaction(&ctrl_socket, "ftp://host", OK);
674 }
675
TEST_F(FtpNetworkTransactionTest,DownloadTransaction)676 TEST_F(FtpNetworkTransactionTest, DownloadTransaction) {
677 FtpSocketDataProviderFileDownload ctrl_socket;
678 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
679 }
680
TEST_F(FtpNetworkTransactionTest,DownloadTransactionMultilineWelcome)681 TEST_F(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) {
682 FtpSocketDataProviderFileDownload ctrl_socket;
683 ctrl_socket.set_multiline_welcome(true);
684 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
685 }
686
TEST_F(FtpNetworkTransactionTest,DownloadTransactionShortReads2)687 TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads2) {
688 FtpSocketDataProviderFileDownload ctrl_socket;
689 ctrl_socket.set_short_read_limit(2);
690 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
691 }
692
TEST_F(FtpNetworkTransactionTest,DownloadTransactionShortReads5)693 TEST_F(FtpNetworkTransactionTest, DownloadTransactionShortReads5) {
694 FtpSocketDataProviderFileDownload ctrl_socket;
695 ctrl_socket.set_short_read_limit(5);
696 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
697 }
698
TEST_F(FtpNetworkTransactionTest,DownloadTransactionVMS)699 TEST_F(FtpNetworkTransactionTest, DownloadTransactionVMS) {
700 FtpSocketDataProviderVMSFileDownload ctrl_socket;
701 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
702 }
703
TEST_F(FtpNetworkTransactionTest,DownloadTransactionAcceptedDataConnection)704 TEST_F(FtpNetworkTransactionTest, DownloadTransactionAcceptedDataConnection) {
705 FtpSocketDataProviderFileDownloadAcceptedDataConnection ctrl_socket;
706 std::string mock_data("mock-data");
707 MockRead data_reads[] = {
708 MockRead(mock_data.c_str()),
709 };
710 StaticSocketDataProvider data_socket1(data_reads, NULL);
711 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
712 mock_socket_factory_.AddSocketDataProvider(&data_socket1);
713 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
714
715 // Start the transaction.
716 ASSERT_EQ(ERR_IO_PENDING,
717 transaction_.Start(&request_info, &callback_, NULL));
718 EXPECT_EQ(OK, callback_.WaitForResult());
719
720 // The transaction fires the callback when we can start reading data.
721 EXPECT_EQ(FtpSocketDataProvider::PRE_QUIT, ctrl_socket.state());
722 EXPECT_EQ(LOAD_STATE_SENDING_REQUEST, transaction_.GetLoadState());
723 scoped_refptr<IOBuffer> io_buffer(new IOBuffer(kBufferSize));
724 memset(io_buffer->data(), 0, kBufferSize);
725 ASSERT_EQ(ERR_IO_PENDING,
726 transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
727 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, transaction_.GetLoadState());
728 EXPECT_EQ(static_cast<int>(mock_data.length()),
729 callback_.WaitForResult());
730 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, transaction_.GetLoadState());
731 EXPECT_EQ(mock_data, std::string(io_buffer->data(), mock_data.length()));
732
733 // FTP server should disconnect the data socket. It is also a signal for the
734 // FtpNetworkTransaction that the data transfer is finished.
735 ClientSocket* data_socket = mock_socket_factory_.GetMockTCPClientSocket(1);
736 ASSERT_TRUE(data_socket);
737 data_socket->Disconnect();
738
739 // We should issue Reads until one returns EOF...
740 ASSERT_EQ(ERR_IO_PENDING,
741 transaction_.Read(io_buffer.get(), kBufferSize, &callback_));
742
743 // Make sure the transaction finishes cleanly.
744 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
745 EXPECT_EQ(OK, callback_.WaitForResult());
746 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket.state());
747 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState());
748 }
749
TEST_F(FtpNetworkTransactionTest,DownloadTransactionTransferStarting)750 TEST_F(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) {
751 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket;
752 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK);
753 }
754
TEST_F(FtpNetworkTransactionTest,DownloadTransactionInvalidResponse)755 TEST_F(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) {
756 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket;
757 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE);
758 }
759
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort1)760 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort1) {
761 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,0,22)\r\n",
762 FtpSocketDataProvider::PRE_QUIT);
763 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
764 }
765
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort2)766 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort2) {
767 // Still unsafe. 1 * 256 + 2 = 258, which is < 1024.
768 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,1,2)\r\n",
769 FtpSocketDataProvider::PRE_QUIT);
770 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
771 }
772
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort3)773 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort3) {
774 // Still unsafe. 3 * 256 + 4 = 772, which is < 1024.
775 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,3,4)\r\n",
776 FtpSocketDataProvider::PRE_QUIT);
777 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
778 }
779
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafePort4)780 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafePort4) {
781 // Unsafe. 8 * 256 + 1 = 2049, which is used by nfs.
782 FtpSocketDataProviderEvilPasv ctrl_socket("227 Portscan (127,0,0,1,8,1)\r\n",
783 FtpSocketDataProvider::PRE_QUIT);
784 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT);
785 }
786
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilPasvUnsafeHost)787 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilPasvUnsafeHost) {
788 FtpSocketDataProviderEvilPasv ctrl_socket(
789 "227 Portscan (10,1,2,3,4,123,456)\r\n", FtpSocketDataProvider::PRE_SIZE);
790 std::string mock_data("mock-data");
791 MockRead data_reads[] = {
792 MockRead(mock_data.c_str()),
793 };
794 StaticSocketDataProvider data_socket1(data_reads, NULL);
795 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket);
796 mock_socket_factory_.AddSocketDataProvider(&data_socket1);
797 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
798
799 // Start the transaction.
800 ASSERT_EQ(ERR_IO_PENDING,
801 transaction_.Start(&request_info, &callback_, NULL));
802 EXPECT_EQ(OK, callback_.WaitForResult());
803
804 // The transaction fires the callback when we can start reading data. That
805 // means that the data socket should be open.
806 MockTCPClientSocket* data_socket =
807 mock_socket_factory_.GetMockTCPClientSocket(1);
808 ASSERT_TRUE(data_socket);
809 ASSERT_TRUE(data_socket->IsConnected());
810
811 // Even if the PASV response specified some other address, we connect
812 // to the address we used for control connection.
813 EXPECT_EQ("127.0.0.1", NetAddressToString(data_socket->addresses().head()));
814
815 // Make sure we have only one host entry in the AddressList.
816 EXPECT_FALSE(data_socket->addresses().head()->ai_next);
817 }
818
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadUsername)819 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) {
820 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test");
821 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK);
822 }
823
TEST_F(FtpNetworkTransactionTest,DownloadTransactionEvilLoginBadPassword)824 TEST_F(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) {
825 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld");
826 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK);
827 }
828
TEST_F(FtpNetworkTransactionTest,DownloadTransactionSpaceInLogin)829 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) {
830 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test");
831 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK);
832 }
833
TEST_F(FtpNetworkTransactionTest,DownloadTransactionSpaceInPassword)834 TEST_F(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) {
835 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world");
836 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK);
837 }
838
TEST_F(FtpNetworkTransactionTest,EvilRestartUser)839 TEST_F(FtpNetworkTransactionTest, EvilRestartUser) {
840 FtpSocketDataProvider ctrl_socket1;
841 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
842 FtpSocketDataProvider::PRE_QUIT,
843 "530 Login authentication failed\r\n");
844 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
845
846 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
847
848 ASSERT_EQ(ERR_IO_PENDING,
849 transaction_.Start(&request_info, &callback_, NULL));
850 EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
851
852 MockRead ctrl_reads[] = {
853 MockRead("220 host TestFTPd\r\n"),
854 MockRead("221 Goodbye!\r\n"),
855 MockRead(false, OK),
856 };
857 MockWrite ctrl_writes[] = {
858 MockWrite("QUIT\r\n"),
859 };
860 StaticSocketDataProvider ctrl_socket2(ctrl_reads, ctrl_writes);
861 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
862 ASSERT_EQ(ERR_IO_PENDING, transaction_.RestartWithAuth(L"foo\nownz0red",
863 L"innocent",
864 &callback_));
865 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
866 }
867
TEST_F(FtpNetworkTransactionTest,EvilRestartPassword)868 TEST_F(FtpNetworkTransactionTest, EvilRestartPassword) {
869 FtpSocketDataProvider ctrl_socket1;
870 ctrl_socket1.InjectFailure(FtpSocketDataProvider::PRE_PASSWD,
871 FtpSocketDataProvider::PRE_QUIT,
872 "530 Login authentication failed\r\n");
873 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket1);
874
875 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file");
876
877 ASSERT_EQ(ERR_IO_PENDING,
878 transaction_.Start(&request_info, &callback_, NULL));
879 EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
880
881 MockRead ctrl_reads[] = {
882 MockRead("220 host TestFTPd\r\n"),
883 MockRead("331 User okay, send password\r\n"),
884 MockRead("221 Goodbye!\r\n"),
885 MockRead(false, OK),
886 };
887 MockWrite ctrl_writes[] = {
888 MockWrite("USER innocent\r\n"),
889 MockWrite("QUIT\r\n"),
890 };
891 StaticSocketDataProvider ctrl_socket2(ctrl_reads, ctrl_writes);
892 mock_socket_factory_.AddSocketDataProvider(&ctrl_socket2);
893 ASSERT_EQ(ERR_IO_PENDING, transaction_.RestartWithAuth(L"innocent",
894 L"foo\nownz0red",
895 &callback_));
896 EXPECT_EQ(ERR_MALFORMED_IDENTITY, callback_.WaitForResult());
897 }
898
TEST_F(FtpNetworkTransactionTest,Escaping)899 TEST_F(FtpNetworkTransactionTest, Escaping) {
900 FtpSocketDataProviderEscaping ctrl_socket;
901 ExecuteTransaction(&ctrl_socket, "ftp://host/%20%21%22%23%24%25%79%80%81",
902 OK);
903 }
904
905 // Regression test for http://crbug.com/25023.
TEST_F(FtpNetworkTransactionTest,CloseConnection)906 TEST_F(FtpNetworkTransactionTest, CloseConnection) {
907 FtpSocketDataProviderCloseConnection ctrl_socket;
908 ExecuteTransaction(&ctrl_socket, "ftp://host", ERR_EMPTY_RESPONSE);
909 }
910
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailUser)911 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailUser) {
912 FtpSocketDataProviderDirectoryListing ctrl_socket;
913 TransactionFailHelper(&ctrl_socket,
914 "ftp://host",
915 FtpSocketDataProvider::PRE_USER,
916 FtpSocketDataProvider::PRE_QUIT,
917 "500 no such user\r\n",
918 ERR_FAILED);
919 }
920
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPass)921 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPass) {
922 FtpSocketDataProviderDirectoryListing ctrl_socket;
923 TransactionFailHelper(&ctrl_socket,
924 "ftp://host",
925 FtpSocketDataProvider::PRE_PASSWD,
926 FtpSocketDataProvider::PRE_QUIT,
927 "530 Login authentication failed\r\n",
928 ERR_FAILED);
929 }
930
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailSyst)931 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailSyst) {
932 FtpSocketDataProviderDirectoryListing ctrl_socket;
933 TransactionFailHelper(&ctrl_socket,
934 "ftp://host",
935 FtpSocketDataProvider::PRE_SYST,
936 FtpSocketDataProvider::PRE_PWD,
937 "500 failed syst\r\n",
938 OK);
939 }
940
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPwd)941 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPwd) {
942 FtpSocketDataProviderDirectoryListing ctrl_socket;
943 TransactionFailHelper(&ctrl_socket,
944 "ftp://host",
945 FtpSocketDataProvider::PRE_PWD,
946 FtpSocketDataProvider::PRE_QUIT,
947 "500 failed pwd\r\n",
948 ERR_FAILED);
949 }
950
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailType)951 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailType) {
952 FtpSocketDataProviderDirectoryListing ctrl_socket;
953 TransactionFailHelper(&ctrl_socket,
954 "ftp://host",
955 FtpSocketDataProvider::PRE_TYPE,
956 FtpSocketDataProvider::PRE_QUIT,
957 "500 failed type\r\n",
958 ERR_FAILED);
959 }
960
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPasv)961 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPasv) {
962 FtpSocketDataProviderDirectoryListing ctrl_socket;
963 TransactionFailHelper(&ctrl_socket,
964 "ftp://host",
965 FtpSocketDataProvider::PRE_PASV,
966 FtpSocketDataProvider::PRE_QUIT,
967 "500 failed pasv\r\n",
968 ERR_FAILED);
969 }
970
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionMalformedMdtm)971 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionMalformedMdtm) {
972 FtpSocketDataProviderDirectoryListing ctrl_socket;
973 TransactionFailHelper(&ctrl_socket,
974 "ftp://host",
975 FtpSocketDataProvider::PRE_MDTM,
976 FtpSocketDataProvider::PRE_RETR,
977 "213 foobar\r\n",
978 OK);
979 }
980
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailMdtm)981 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailMdtm) {
982 FtpSocketDataProviderDirectoryListing ctrl_socket;
983 TransactionFailHelper(&ctrl_socket,
984 "ftp://host",
985 FtpSocketDataProvider::PRE_MDTM,
986 FtpSocketDataProvider::PRE_RETR,
987 "500 failed mdtm\r\n",
988 OK);
989 }
990
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailPasv2)991 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailPasv2) {
992 FtpSocketDataProviderDirectoryListing ctrl_socket;
993 TransactionFailHelper(&ctrl_socket,
994 "ftp://host",
995 FtpSocketDataProvider::PRE_PASV2,
996 FtpSocketDataProvider::PRE_QUIT,
997 "500 failed pasv2\r\n",
998 ERR_FAILED);
999 }
1000
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailCwd)1001 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailCwd) {
1002 FtpSocketDataProviderDirectoryListing ctrl_socket;
1003 TransactionFailHelper(&ctrl_socket,
1004 "ftp://host",
1005 FtpSocketDataProvider::PRE_CWD,
1006 FtpSocketDataProvider::PRE_QUIT,
1007 "500 failed cwd\r\n",
1008 ERR_FAILED);
1009 }
1010
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFileNotFound)1011 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFileNotFound) {
1012 FtpSocketDataProviderDirectoryListing ctrl_socket;
1013 TransactionFailHelper(&ctrl_socket,
1014 "ftp://host",
1015 FtpSocketDataProvider::PRE_CWD,
1016 FtpSocketDataProvider::PRE_QUIT,
1017 "550 cannot open file\r\n",
1018 ERR_FILE_NOT_FOUND);
1019 }
1020
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailMlsd)1021 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailMlsd) {
1022 FtpSocketDataProviderDirectoryListing ctrl_socket;
1023 TransactionFailHelper(&ctrl_socket,
1024 "ftp://host",
1025 FtpSocketDataProvider::PRE_MLSD,
1026 FtpSocketDataProvider::PRE_LIST,
1027 "500 Unrecognized command\r\n",
1028 OK);
1029 }
1030
TEST_F(FtpNetworkTransactionTest,DirectoryTransactionFailList)1031 TEST_F(FtpNetworkTransactionTest, DirectoryTransactionFailList) {
1032 FtpSocketDataProviderVMSDirectoryListing ctrl_socket;
1033 TransactionFailHelper(&ctrl_socket,
1034 "ftp://host/dir",
1035 FtpSocketDataProvider::PRE_LIST,
1036 FtpSocketDataProvider::PRE_QUIT,
1037 "500 failed list\r\n",
1038 ERR_FAILED);
1039 }
1040
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailUser)1041 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailUser) {
1042 FtpSocketDataProviderFileDownload ctrl_socket;
1043 TransactionFailHelper(&ctrl_socket,
1044 "ftp://host/file",
1045 FtpSocketDataProvider::PRE_USER,
1046 FtpSocketDataProvider::PRE_QUIT,
1047 "500 no such user\r\n",
1048 ERR_FAILED);
1049 }
1050
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPass)1051 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPass) {
1052 FtpSocketDataProviderFileDownload ctrl_socket;
1053 TransactionFailHelper(&ctrl_socket,
1054 "ftp://host/file",
1055 FtpSocketDataProvider::PRE_PASSWD,
1056 FtpSocketDataProvider::PRE_QUIT,
1057 "530 Login authentication failed\r\n",
1058 ERR_FAILED);
1059 }
1060
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailSyst)1061 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailSyst) {
1062 FtpSocketDataProviderFileDownload ctrl_socket;
1063 TransactionFailHelper(&ctrl_socket,
1064 "ftp://host/file",
1065 FtpSocketDataProvider::PRE_SYST,
1066 FtpSocketDataProvider::PRE_PWD,
1067 "500 failed syst\r\n",
1068 OK);
1069 }
1070
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPwd)1071 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPwd) {
1072 FtpSocketDataProviderFileDownload ctrl_socket;
1073 TransactionFailHelper(&ctrl_socket,
1074 "ftp://host/file",
1075 FtpSocketDataProvider::PRE_PWD,
1076 FtpSocketDataProvider::PRE_QUIT,
1077 "500 failed pwd\r\n",
1078 ERR_FAILED);
1079 }
1080
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailType)1081 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailType) {
1082 FtpSocketDataProviderFileDownload ctrl_socket;
1083 TransactionFailHelper(&ctrl_socket,
1084 "ftp://host/file",
1085 FtpSocketDataProvider::PRE_TYPE,
1086 FtpSocketDataProvider::PRE_QUIT,
1087 "500 failed type\r\n",
1088 ERR_FAILED);
1089 }
1090
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailPasv)1091 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailPasv) {
1092 FtpSocketDataProviderFileDownload ctrl_socket;
1093 TransactionFailHelper(&ctrl_socket,
1094 "ftp://host/file",
1095 FtpSocketDataProvider::PRE_PASV,
1096 FtpSocketDataProvider::PRE_QUIT,
1097 "500 failed pasv\r\n",
1098 ERR_FAILED);
1099 }
1100
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailMdtm)1101 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailMdtm) {
1102 FtpSocketDataProviderFileDownload ctrl_socket;
1103 TransactionFailHelper(&ctrl_socket,
1104 "ftp://host/file",
1105 FtpSocketDataProvider::PRE_MDTM,
1106 FtpSocketDataProvider::PRE_RETR,
1107 "500 failed mdtm\r\n",
1108 OK);
1109 }
1110
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFailRetr)1111 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFailRetr) {
1112 FtpSocketDataProviderFileDownloadRetrFail ctrl_socket;
1113 TransactionFailHelper(&ctrl_socket,
1114 "ftp://host/file",
1115 FtpSocketDataProvider::PRE_RETR,
1116 FtpSocketDataProvider::PRE_QUIT,
1117 "500 failed retr\r\n",
1118 ERR_FAILED);
1119 }
1120
TEST_F(FtpNetworkTransactionTest,DownloadTransactionFileNotFound)1121 TEST_F(FtpNetworkTransactionTest, DownloadTransactionFileNotFound) {
1122 FtpSocketDataProviderFileDownloadRetrFail ctrl_socket;
1123 TransactionFailHelper(&ctrl_socket,
1124 "ftp://host/file",
1125 FtpSocketDataProvider::PRE_RETR,
1126 FtpSocketDataProvider::PRE_PASV2,
1127 "550 cannot open file\r\n",
1128 ERR_FILE_NOT_FOUND);
1129 }
1130
1131 } // namespace net
1132