OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/ftp/ftp_network_transaction.h" | |
6 | |
7 #include "build/build_config.h" | |
8 | |
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" | |
24 | |
25 namespace { | |
26 | |
27 // Size we use for IOBuffers used to receive data from the test data socket. | |
28 const int kBufferSize = 128; | |
29 | |
30 } // namespace | |
31 | |
32 namespace net { | |
33 | |
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 | |
54 }; | |
55 | |
56 FtpSocketDataProvider() | |
57 : failure_injection_state_(NONE), | |
58 multiline_welcome_(false), | |
59 use_epsv_(true), | |
60 data_type_('I') { | |
61 Init(); | |
62 } | |
63 | |
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: | |
72 { | |
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); | |
78 } | |
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); | |
109 } | |
110 } | |
111 | |
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; | |
120 } | |
121 | |
122 State state() const { | |
123 return state_; | |
124 } | |
125 | |
126 void Reset() override { | |
127 DynamicSocketDataProvider::Reset(); | |
128 Init(); | |
129 } | |
130 | |
131 void set_multiline_welcome(bool multiline) { multiline_welcome_ = multiline; } | |
132 | |
133 bool use_epsv() const { return use_epsv_; } | |
134 void set_use_epsv(bool use_epsv) { use_epsv_ = use_epsv; } | |
135 | |
136 void set_data_type(char data_type) { data_type_ = data_type; } | |
137 | |
138 protected: | |
139 void Init() { | |
140 state_ = PRE_USER; | |
141 SimulateRead("220 host TestFTPd\r\n"); | |
142 } | |
143 | |
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; | |
152 } | |
153 | |
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()); | |
164 } | |
165 return MockWriteResult(ASYNC, ERR_UNEXPECTED); | |
166 } | |
167 | |
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)); | |
174 } | |
175 | |
176 | |
177 private: | |
178 State state_; | |
179 State failure_injection_state_; | |
180 State failure_injection_next_state_; | |
181 const char* fault_response_; | |
182 | |
183 // If true, we will send multiple 230 lines as response after PASS. | |
184 bool multiline_welcome_; | |
185 | |
186 // If true, we will use EPSV command. | |
187 bool use_epsv_; | |
188 | |
189 // Data type to be used for TYPE command. | |
190 char data_type_; | |
191 | |
192 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProvider); | |
193 }; | |
194 | |
195 class FtpSocketDataProviderDirectoryListing : public FtpSocketDataProvider { | |
196 public: | |
197 FtpSocketDataProviderDirectoryListing() { | |
198 } | |
199 | |
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); | |
214 } | |
215 } | |
216 | |
217 private: | |
218 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListing); | |
219 }; | |
220 | |
221 class FtpSocketDataProviderDirectoryListingWithPasvFallback | |
222 : public FtpSocketDataProviderDirectoryListing { | |
223 public: | |
224 FtpSocketDataProviderDirectoryListingWithPasvFallback() { | |
225 } | |
226 | |
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); | |
239 } | |
240 } | |
241 | |
242 private: | |
243 DISALLOW_COPY_AND_ASSIGN( | |
244 FtpSocketDataProviderDirectoryListingWithPasvFallback); | |
245 }; | |
246 | |
247 class FtpSocketDataProviderDirectoryListingZeroSize | |
248 : public FtpSocketDataProviderDirectoryListing { | |
249 public: | |
250 FtpSocketDataProviderDirectoryListingZeroSize() { | |
251 } | |
252 | |
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); | |
261 } | |
262 } | |
263 | |
264 private: | |
265 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderDirectoryListingZeroSize); | |
266 }; | |
267 | |
268 class FtpSocketDataProviderVMSDirectoryListing : public FtpSocketDataProvider { | |
269 public: | |
270 FtpSocketDataProviderVMSDirectoryListing() { | |
271 } | |
272 | |
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); | |
295 } | |
296 } | |
297 | |
298 private: | |
299 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSDirectoryListing); | |
300 }; | |
301 | |
302 class FtpSocketDataProviderVMSDirectoryListingRootDirectory | |
303 : public FtpSocketDataProvider { | |
304 public: | |
305 FtpSocketDataProviderVMSDirectoryListingRootDirectory() { | |
306 } | |
307 | |
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); | |
330 } | |
331 } | |
332 | |
333 private: | |
334 DISALLOW_COPY_AND_ASSIGN( | |
335 FtpSocketDataProviderVMSDirectoryListingRootDirectory); | |
336 }; | |
337 | |
338 class FtpSocketDataProviderFileDownloadWithFileTypecode | |
339 : public FtpSocketDataProvider { | |
340 public: | |
341 FtpSocketDataProviderFileDownloadWithFileTypecode() { | |
342 } | |
343 | |
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); | |
355 } | |
356 } | |
357 | |
358 private: | |
359 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode); | |
360 }; | |
361 | |
362 class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider { | |
363 public: | |
364 FtpSocketDataProviderFileDownload() { | |
365 } | |
366 | |
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); | |
381 } | |
382 } | |
383 | |
384 private: | |
385 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownload); | |
386 }; | |
387 | |
388 class FtpSocketDataProviderFileNotFound : public FtpSocketDataProvider { | |
389 public: | |
390 FtpSocketDataProviderFileNotFound() { | |
391 } | |
392 | |
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); | |
409 } | |
410 } | |
411 | |
412 private: | |
413 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileNotFound); | |
414 }; | |
415 | |
416 class FtpSocketDataProviderFileDownloadWithPasvFallback | |
417 : public FtpSocketDataProviderFileDownload { | |
418 public: | |
419 FtpSocketDataProviderFileDownloadWithPasvFallback() { | |
420 } | |
421 | |
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); | |
434 } | |
435 } | |
436 | |
437 private: | |
438 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithPasvFallback); | |
439 }; | |
440 | |
441 class FtpSocketDataProviderFileDownloadZeroSize | |
442 : public FtpSocketDataProviderFileDownload { | |
443 public: | |
444 FtpSocketDataProviderFileDownloadZeroSize() { | |
445 } | |
446 | |
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); | |
460 } | |
461 } | |
462 | |
463 private: | |
464 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadZeroSize); | |
465 }; | |
466 | |
467 class FtpSocketDataProviderFileDownloadCWD451 | |
468 : public FtpSocketDataProviderFileDownload { | |
469 public: | |
470 FtpSocketDataProviderFileDownloadCWD451() { | |
471 } | |
472 | |
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); | |
483 } | |
484 } | |
485 | |
486 private: | |
487 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadCWD451); | |
488 }; | |
489 | |
490 class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider { | |
491 public: | |
492 FtpSocketDataProviderVMSFileDownload() { | |
493 } | |
494 | |
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); | |
519 } | |
520 } | |
521 | |
522 private: | |
523 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderVMSFileDownload); | |
524 }; | |
525 | |
526 class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload { | |
527 public: | |
528 FtpSocketDataProviderEscaping() { | |
529 } | |
530 | |
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); | |
547 } | |
548 } | |
549 | |
550 private: | |
551 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEscaping); | |
552 }; | |
553 | |
554 class FtpSocketDataProviderFileDownloadTransferStarting | |
555 : public FtpSocketDataProviderFileDownload { | |
556 public: | |
557 FtpSocketDataProviderFileDownloadTransferStarting() { | |
558 } | |
559 | |
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); | |
571 } | |
572 } | |
573 | |
574 private: | |
575 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadTransferStarting); | |
576 }; | |
577 | |
578 class FtpSocketDataProviderDirectoryListingTransferStarting | |
579 : public FtpSocketDataProviderDirectoryListing { | |
580 public: | |
581 FtpSocketDataProviderDirectoryListingTransferStarting() { | |
582 } | |
583 | |
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); | |
595 } | |
596 } | |
597 | |
598 private: | |
599 DISALLOW_COPY_AND_ASSIGN( | |
600 FtpSocketDataProviderDirectoryListingTransferStarting); | |
601 }; | |
602 | |
603 class FtpSocketDataProviderFileDownloadInvalidResponse | |
604 : public FtpSocketDataProviderFileDownload { | |
605 public: | |
606 FtpSocketDataProviderFileDownloadInvalidResponse() { | |
607 } | |
608 | |
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); | |
621 } | |
622 } | |
623 | |
624 private: | |
625 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadInvalidResponse); | |
626 }; | |
627 | |
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) {} | |
635 | |
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) {} | |
642 | |
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); | |
652 } | |
653 } | |
654 | |
655 private: | |
656 const char* epsv_response_; | |
657 const size_t epsv_response_length_; | |
658 const State expected_state_; | |
659 | |
660 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilEpsv); | |
661 }; | |
662 | |
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) { | |
669 } | |
670 | |
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); | |
679 } | |
680 } | |
681 | |
682 private: | |
683 const char* pasv_response_; | |
684 const State expected_state_; | |
685 | |
686 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilPasv); | |
687 }; | |
688 | |
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) { | |
694 } | |
695 | |
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); | |
704 } | |
705 } | |
706 | |
707 private: | |
708 const char* size_response_; | |
709 const State expected_state_; | |
710 | |
711 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilSize); | |
712 }; | |
713 | |
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) { | |
721 } | |
722 | |
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); | |
735 } | |
736 } | |
737 | |
738 private: | |
739 const char* expected_user_; | |
740 const char* expected_password_; | |
741 | |
742 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderEvilLogin); | |
743 }; | |
744 | |
745 class FtpSocketDataProviderCloseConnection : public FtpSocketDataProvider { | |
746 public: | |
747 FtpSocketDataProviderCloseConnection() { | |
748 } | |
749 | |
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); | |
759 } | |
760 } | |
761 | |
762 private: | |
763 DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderCloseConnection); | |
764 }; | |
765 | |
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(); | |
782 } | |
783 host_resolver_->set_rules(rules.get()); | |
784 } | |
785 | |
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(); | |
791 } | |
792 | |
793 FtpRequestInfo GetRequestInfo(const std::string& url) { | |
794 FtpRequestInfo info; | |
795 info.url = GURL(url); | |
796 return info; | |
797 } | |
798 | |
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)); | |
804 | |
805 mock_socket_factory_.AddSocketDataProvider(ctrl_socket); | |
806 | |
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()), | |
813 }; | |
814 | |
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())); | |
835 | |
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); | |
843 } | |
844 } | |
845 EXPECT_EQ(FtpSocketDataProvider::QUIT, ctrl_socket->state()); | |
846 EXPECT_EQ(LOAD_STATE_IDLE, transaction_.GetLoadState()); | |
847 } | |
848 | |
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); | |
857 } | |
858 | |
859 scoped_ptr<MockHostResolver> host_resolver_; | |
860 scoped_refptr<FtpNetworkSession> session_; | |
861 MockClientSocketFactory mock_socket_factory_; | |
862 FtpNetworkTransaction transaction_; | |
863 TestCompletionCallback callback_; | |
864 }; | |
865 | |
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()); | |
872 | |
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()); | |
879 } | |
880 | |
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; | |
887 | |
888 host_resolver_->rules()->AddSimulatedFailure("[::1]"); | |
889 | |
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); | |
898 } | |
899 | |
900 TEST_P(FtpNetworkTransactionTest, DirectoryTransaction) { | |
901 FtpSocketDataProviderDirectoryListing ctrl_socket; | |
902 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
903 | |
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()); | |
909 } | |
910 | |
911 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithPasvFallback) { | |
912 FtpSocketDataProviderDirectoryListingWithPasvFallback ctrl_socket; | |
913 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
914 | |
915 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); | |
916 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); | |
917 } | |
918 | |
919 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionWithTypecode) { | |
920 FtpSocketDataProviderDirectoryListing ctrl_socket; | |
921 ExecuteTransaction(&ctrl_socket, "ftp://host/;type=d", OK); | |
922 | |
923 EXPECT_TRUE(transaction_.GetResponseInfo()->is_directory_listing); | |
924 EXPECT_EQ(-1, transaction_.GetResponseInfo()->expected_content_size); | |
925 } | |
926 | |
927 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionMultilineWelcome) { | |
928 FtpSocketDataProviderDirectoryListing ctrl_socket; | |
929 ctrl_socket.set_multiline_welcome(true); | |
930 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
931 } | |
932 | |
933 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads2) { | |
934 FtpSocketDataProviderDirectoryListing ctrl_socket; | |
935 ctrl_socket.set_short_read_limit(2); | |
936 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
937 } | |
938 | |
939 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionShortReads5) { | |
940 FtpSocketDataProviderDirectoryListing ctrl_socket; | |
941 ctrl_socket.set_short_read_limit(5); | |
942 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
943 } | |
944 | |
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); | |
953 } | |
954 | |
955 // Regression test for http://crbug.com/60555. | |
956 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionZeroSize) { | |
957 FtpSocketDataProviderDirectoryListingZeroSize ctrl_socket; | |
958 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
959 } | |
960 | |
961 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMS) { | |
962 FtpSocketDataProviderVMSDirectoryListing ctrl_socket; | |
963 ExecuteTransaction(&ctrl_socket, "ftp://host/dir", OK); | |
964 } | |
965 | |
966 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionVMSRootDirectory) { | |
967 FtpSocketDataProviderVMSDirectoryListingRootDirectory ctrl_socket; | |
968 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
969 } | |
970 | |
971 TEST_P(FtpNetworkTransactionTest, DirectoryTransactionTransferStarting) { | |
972 FtpSocketDataProviderDirectoryListingTransferStarting ctrl_socket; | |
973 ExecuteTransaction(&ctrl_socket, "ftp://host", OK); | |
974 } | |
975 | |
976 TEST_P(FtpNetworkTransactionTest, DownloadTransaction) { | |
977 FtpSocketDataProviderFileDownload ctrl_socket; | |
978 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
979 | |
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()); | |
985 } | |
986 | |
987 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) { | |
988 FtpSocketDataProviderFileDownloadWithPasvFallback ctrl_socket; | |
989 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
990 | |
991 // We pass an artificial value of 18 as a response to the SIZE command. | |
992 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); | |
993 } | |
994 | |
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); | |
999 | |
1000 // We pass an artificial value of 18 as a response to the SIZE command. | |
1001 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); | |
1002 } | |
1003 | |
1004 TEST_P(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) { | |
1005 FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; | |
1006 ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK); | |
1007 | |
1008 // We pass an artificial value of 18 as a response to the SIZE command. | |
1009 EXPECT_EQ(18, transaction_.GetResponseInfo()->expected_content_size); | |
1010 } | |
1011 | |
1012 TEST_P(FtpNetworkTransactionTest, DownloadTransactionMultilineWelcome) { | |
1013 FtpSocketDataProviderFileDownload ctrl_socket; | |
1014 ctrl_socket.set_multiline_welcome(true); | |
1015 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1016 } | |
1017 | |
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); | |
1022 } | |
1023 | |
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); | |
1028 } | |
1029 | |
1030 TEST_P(FtpNetworkTransactionTest, DownloadTransactionZeroSize) { | |
1031 FtpSocketDataProviderFileDownloadZeroSize ctrl_socket; | |
1032 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1033 } | |
1034 | |
1035 TEST_P(FtpNetworkTransactionTest, DownloadTransactionCWD451) { | |
1036 FtpSocketDataProviderFileDownloadCWD451 ctrl_socket; | |
1037 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1038 } | |
1039 | |
1040 TEST_P(FtpNetworkTransactionTest, DownloadTransactionVMS) { | |
1041 FtpSocketDataProviderVMSFileDownload ctrl_socket; | |
1042 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1043 } | |
1044 | |
1045 TEST_P(FtpNetworkTransactionTest, DownloadTransactionTransferStarting) { | |
1046 FtpSocketDataProviderFileDownloadTransferStarting ctrl_socket; | |
1047 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1048 } | |
1049 | |
1050 TEST_P(FtpNetworkTransactionTest, DownloadTransactionInvalidResponse) { | |
1051 FtpSocketDataProviderFileDownloadInvalidResponse ctrl_socket; | |
1052 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); | |
1053 } | |
1054 | |
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); | |
1059 } | |
1060 | |
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); | |
1065 } | |
1066 | |
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); | |
1072 } | |
1073 | |
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); | |
1079 } | |
1080 | |
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); | |
1086 } | |
1087 | |
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()), | |
1095 }; | |
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"); | |
1103 | |
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()); | |
1109 | |
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()); | |
1116 | |
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()); | |
1123 } | |
1124 } | |
1125 | |
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; | |
1130 | |
1131 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22)\r\n", | |
1132 FtpSocketDataProvider::PRE_QUIT); | |
1133 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); | |
1134 } | |
1135 | |
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; | |
1140 | |
1141 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||\r\n", | |
1142 FtpSocketDataProvider::PRE_QUIT); | |
1143 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); | |
1144 } | |
1145 | |
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; | |
1150 | |
1151 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan\r\n", | |
1152 FtpSocketDataProvider::PRE_QUIT); | |
1153 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); | |
1154 } | |
1155 | |
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; | |
1160 | |
1161 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (||||)\r\n", | |
1162 FtpSocketDataProvider::PRE_QUIT); | |
1163 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_INVALID_RESPONSE); | |
1164 } | |
1165 | |
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; | |
1170 | |
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); | |
1176 } | |
1177 | |
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; | |
1182 | |
1183 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||22|)\r\n", | |
1184 FtpSocketDataProvider::PRE_QUIT); | |
1185 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); | |
1186 } | |
1187 | |
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; | |
1192 | |
1193 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||258|)\r\n", | |
1194 FtpSocketDataProvider::PRE_QUIT); | |
1195 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); | |
1196 } | |
1197 | |
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; | |
1202 | |
1203 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||772|)\r\n", | |
1204 FtpSocketDataProvider::PRE_QUIT); | |
1205 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); | |
1206 } | |
1207 | |
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; | |
1212 | |
1213 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan (|||2049|)\r\n", | |
1214 FtpSocketDataProvider::PRE_QUIT); | |
1215 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); | |
1216 } | |
1217 | |
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; | |
1222 | |
1223 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$31744$)\r\n", | |
1224 FtpSocketDataProvider::PRE_RETR); | |
1225 ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); | |
1226 } | |
1227 | |
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; | |
1233 | |
1234 FtpSocketDataProviderEvilEpsv ctrl_socket("227 Portscan ($$$317$)\r\n", | |
1235 FtpSocketDataProvider::PRE_QUIT); | |
1236 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_UNSAFE_PORT); | |
1237 } | |
1238 | |
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; | |
1243 | |
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); | |
1247 } | |
1248 | |
1249 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadUsername) { | |
1250 FtpSocketDataProviderEvilLogin ctrl_socket("hello%0Aworld", "test"); | |
1251 ExecuteTransaction(&ctrl_socket, "ftp://hello%0Aworld:test@host/file", OK); | |
1252 } | |
1253 | |
1254 TEST_P(FtpNetworkTransactionTest, DownloadTransactionEvilLoginBadPassword) { | |
1255 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello%0Dworld"); | |
1256 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%0Dworld@host/file", OK); | |
1257 } | |
1258 | |
1259 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInLogin) { | |
1260 FtpSocketDataProviderEvilLogin ctrl_socket("hello world", "test"); | |
1261 ExecuteTransaction(&ctrl_socket, "ftp://hello%20world:test@host/file", OK); | |
1262 } | |
1263 | |
1264 TEST_P(FtpNetworkTransactionTest, DownloadTransactionSpaceInPassword) { | |
1265 FtpSocketDataProviderEvilLogin ctrl_socket("test", "hello world"); | |
1266 ExecuteTransaction(&ctrl_socket, "ftp://test:hello%20world@host/file", OK); | |
1267 } | |
1268 | |
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); | |
1275 | |
1276 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); | |
1277 | |
1278 ASSERT_EQ(ERR_IO_PENDING, | |
1279 transaction_.Start(&request_info, callback_.callback(), | |
1280 BoundNetLog())); | |
1281 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); | |
1282 | |
1283 MockRead ctrl_reads[] = { | |
1284 MockRead("220 host TestFTPd\r\n"), | |
1285 MockRead("221 Goodbye!\r\n"), | |
1286 MockRead(SYNCHRONOUS, OK), | |
1287 }; | |
1288 MockWrite ctrl_writes[] = { | |
1289 MockWrite("QUIT\r\n"), | |
1290 }; | |
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()); | |
1301 } | |
1302 | |
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); | |
1309 | |
1310 FtpRequestInfo request_info = GetRequestInfo("ftp://host/file"); | |
1311 | |
1312 ASSERT_EQ(ERR_IO_PENDING, | |
1313 transaction_.Start(&request_info, callback_.callback(), | |
1314 BoundNetLog())); | |
1315 ASSERT_EQ(ERR_FTP_FAILED, callback_.WaitForResult()); | |
1316 | |
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), | |
1322 }; | |
1323 MockWrite ctrl_writes[] = { | |
1324 MockWrite("USER innocent\r\n"), | |
1325 MockWrite("QUIT\r\n"), | |
1326 }; | |
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()); | |
1336 } | |
1337 | |
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); | |
1342 } | |
1343 | |
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); | |
1351 } | |
1352 | |
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); | |
1362 } | |
1363 | |
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); | |
1368 } | |
1369 | |
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); | |
1380 } | |
1381 | |
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); | |
1390 } | |
1391 | |
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); | |
1401 } | |
1402 | |
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); | |
1413 } | |
1414 | |
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); | |
1425 } | |
1426 | |
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); | |
1437 } | |
1438 | |
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; | |
1443 | |
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); | |
1450 } | |
1451 | |
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); | |
1462 } | |
1463 | |
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); | |
1474 } | |
1475 | |
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); | |
1486 } | |
1487 | |
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); | |
1496 } | |
1497 | |
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); | |
1508 } | |
1509 | |
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); | |
1520 } | |
1521 | |
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); | |
1532 } | |
1533 | |
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; | |
1538 | |
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); | |
1545 } | |
1546 | |
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); | |
1557 } | |
1558 | |
1559 TEST_P(FtpNetworkTransactionTest, FileNotFound) { | |
1560 FtpSocketDataProviderFileNotFound ctrl_socket; | |
1561 ExecuteTransaction(&ctrl_socket, "ftp://host/file", ERR_FTP_FAILED); | |
1562 } | |
1563 | |
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); | |
1573 } | |
1574 | |
1575 INSTANTIATE_TEST_CASE_P(FTP, | |
1576 FtpNetworkTransactionTest, | |
1577 ::testing::Values(AF_INET, AF_INET6)); | |
1578 | |
1579 } // namespace net | |
OLD | NEW |