OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // source code is governed by a BSD-style license that can be found in the | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/ftp/ftp_network_transaction.h" | 5 #include "net/ftp/ftp_network_transaction.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/histogram.h" | 8 #include "base/histogram.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "net/base/connection_type_histograms.h" | 11 #include "net/base/connection_type_histograms.h" |
12 #include "net/base/escape.h" | 12 #include "net/base/escape.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 143 |
144 if (request_->url.has_username()) { | 144 if (request_->url.has_username()) { |
145 GetIdentityFromURL(request_->url, &username_, &password_); | 145 GetIdentityFromURL(request_->url, &username_, &password_); |
146 } else { | 146 } else { |
147 username_ = L"anonymous"; | 147 username_ = L"anonymous"; |
148 password_ = L"chrome@example.com"; | 148 password_ = L"chrome@example.com"; |
149 } | 149 } |
150 | 150 |
151 DetectTypecode(); | 151 DetectTypecode(); |
152 | 152 |
153 next_state_ = STATE_CTRL_INIT; | 153 next_state_ = STATE_CTRL_RESOLVE_HOST; |
154 int rv = DoLoop(OK); | 154 int rv = DoLoop(OK); |
155 if (rv == ERR_IO_PENDING) | 155 if (rv == ERR_IO_PENDING) |
156 user_callback_ = callback; | 156 user_callback_ = callback; |
157 return rv; | 157 return rv; |
158 } | 158 } |
159 | 159 |
160 int FtpNetworkTransaction::Stop(int error) { | 160 int FtpNetworkTransaction::Stop(int error) { |
161 if (command_sent_ == COMMAND_QUIT) | 161 if (command_sent_ == COMMAND_QUIT) |
162 return error; | 162 return error; |
163 | 163 |
164 next_state_ = STATE_CTRL_WRITE_QUIT; | 164 next_state_ = STATE_CTRL_WRITE_QUIT; |
165 last_error_ = error; | 165 last_error_ = error; |
166 return OK; | 166 return OK; |
167 } | 167 } |
168 | 168 |
169 int FtpNetworkTransaction::RestartWithAuth(const std::wstring& username, | 169 int FtpNetworkTransaction::RestartWithAuth(const std::wstring& username, |
170 const std::wstring& password, | 170 const std::wstring& password, |
171 CompletionCallback* callback) { | 171 CompletionCallback* callback) { |
172 ResetStateForRestart(); | 172 ResetStateForRestart(); |
173 | 173 |
174 username_ = username; | 174 username_ = username; |
175 password_ = password; | 175 password_ = password; |
176 | 176 |
177 next_state_ = STATE_CTRL_INIT; | 177 next_state_ = STATE_CTRL_RESOLVE_HOST; |
178 int rv = DoLoop(OK); | 178 int rv = DoLoop(OK); |
179 if (rv == ERR_IO_PENDING) | 179 if (rv == ERR_IO_PENDING) |
180 user_callback_ = callback; | 180 user_callback_ = callback; |
181 return rv; | 181 return rv; |
182 } | 182 } |
183 | 183 |
184 int FtpNetworkTransaction::RestartIgnoringLastError( | 184 int FtpNetworkTransaction::RestartIgnoringLastError( |
185 CompletionCallback* callback) { | 185 CompletionCallback* callback) { |
186 return ERR_FAILED; | 186 return ERR_FAILED; |
187 } | 187 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 case COMMAND_NONE: | 294 case COMMAND_NONE: |
295 // TODO(phajdan.jr): Check for errors in the welcome message. | 295 // TODO(phajdan.jr): Check for errors in the welcome message. |
296 next_state_ = STATE_CTRL_WRITE_USER; | 296 next_state_ = STATE_CTRL_WRITE_USER; |
297 break; | 297 break; |
298 case COMMAND_USER: | 298 case COMMAND_USER: |
299 rv = ProcessResponseUSER(response); | 299 rv = ProcessResponseUSER(response); |
300 break; | 300 break; |
301 case COMMAND_PASS: | 301 case COMMAND_PASS: |
302 rv = ProcessResponsePASS(response); | 302 rv = ProcessResponsePASS(response); |
303 break; | 303 break; |
304 case COMMAND_ACCT: | |
305 rv = ProcessResponseACCT(response); | |
306 break; | |
307 case COMMAND_SYST: | 304 case COMMAND_SYST: |
308 rv = ProcessResponseSYST(response); | 305 rv = ProcessResponseSYST(response); |
309 break; | 306 break; |
310 case COMMAND_PWD: | 307 case COMMAND_PWD: |
311 rv = ProcessResponsePWD(response); | 308 rv = ProcessResponsePWD(response); |
312 break; | 309 break; |
313 case COMMAND_TYPE: | 310 case COMMAND_TYPE: |
314 rv = ProcessResponseTYPE(response); | 311 rv = ProcessResponseTYPE(response); |
315 break; | 312 break; |
316 case COMMAND_EPSV: | 313 case COMMAND_EPSV: |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 } | 452 } |
456 | 453 |
457 int FtpNetworkTransaction::DoLoop(int result) { | 454 int FtpNetworkTransaction::DoLoop(int result) { |
458 DCHECK(next_state_ != STATE_NONE); | 455 DCHECK(next_state_ != STATE_NONE); |
459 | 456 |
460 int rv = result; | 457 int rv = result; |
461 do { | 458 do { |
462 State state = next_state_; | 459 State state = next_state_; |
463 next_state_ = STATE_NONE; | 460 next_state_ = STATE_NONE; |
464 switch (state) { | 461 switch (state) { |
465 case STATE_CTRL_INIT: | |
466 DCHECK(rv == OK); | |
467 rv = DoCtrlInit(); | |
468 break; | |
469 case STATE_CTRL_INIT_COMPLETE: | |
470 rv = DoCtrlInitComplete(rv); | |
471 break; | |
472 case STATE_CTRL_RESOLVE_HOST: | 462 case STATE_CTRL_RESOLVE_HOST: |
473 DCHECK(rv == OK); | 463 DCHECK(rv == OK); |
474 rv = DoCtrlResolveHost(); | 464 rv = DoCtrlResolveHost(); |
475 break; | 465 break; |
476 case STATE_CTRL_RESOLVE_HOST_COMPLETE: | 466 case STATE_CTRL_RESOLVE_HOST_COMPLETE: |
477 rv = DoCtrlResolveHostComplete(rv); | 467 rv = DoCtrlResolveHostComplete(rv); |
478 break; | 468 break; |
479 case STATE_CTRL_CONNECT: | 469 case STATE_CTRL_CONNECT: |
480 DCHECK(rv == OK); | 470 DCHECK(rv == OK); |
481 rv = DoCtrlConnect(); | 471 rv = DoCtrlConnect(); |
(...skipping 20 matching lines...) Expand all Loading... |
502 rv = DoCtrlWriteUSER(); | 492 rv = DoCtrlWriteUSER(); |
503 break; | 493 break; |
504 case STATE_CTRL_WRITE_PASS: | 494 case STATE_CTRL_WRITE_PASS: |
505 DCHECK(rv == OK); | 495 DCHECK(rv == OK); |
506 rv = DoCtrlWritePASS(); | 496 rv = DoCtrlWritePASS(); |
507 break; | 497 break; |
508 case STATE_CTRL_WRITE_SYST: | 498 case STATE_CTRL_WRITE_SYST: |
509 DCHECK(rv == OK); | 499 DCHECK(rv == OK); |
510 rv = DoCtrlWriteSYST(); | 500 rv = DoCtrlWriteSYST(); |
511 break; | 501 break; |
512 case STATE_CTRL_WRITE_ACCT: | |
513 DCHECK(rv == OK); | |
514 rv = DoCtrlWriteACCT(); | |
515 break; | |
516 case STATE_CTRL_WRITE_PWD: | 502 case STATE_CTRL_WRITE_PWD: |
517 DCHECK(rv == OK); | 503 DCHECK(rv == OK); |
518 rv = DoCtrlWritePWD(); | 504 rv = DoCtrlWritePWD(); |
519 break; | 505 break; |
520 case STATE_CTRL_WRITE_TYPE: | 506 case STATE_CTRL_WRITE_TYPE: |
521 DCHECK(rv == OK); | 507 DCHECK(rv == OK); |
522 rv = DoCtrlWriteTYPE(); | 508 rv = DoCtrlWriteTYPE(); |
523 break; | 509 break; |
524 case STATE_CTRL_WRITE_EPSV: | 510 case STATE_CTRL_WRITE_EPSV: |
525 DCHECK(rv == OK); | 511 DCHECK(rv == OK); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 break; | 555 break; |
570 default: | 556 default: |
571 NOTREACHED() << "bad state"; | 557 NOTREACHED() << "bad state"; |
572 rv = ERR_UNEXPECTED; | 558 rv = ERR_UNEXPECTED; |
573 break; | 559 break; |
574 } | 560 } |
575 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 561 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
576 return rv; | 562 return rv; |
577 } | 563 } |
578 | 564 |
579 // TODO(ibrar): Yet to see if we need any intialization | |
580 int FtpNetworkTransaction::DoCtrlInit() { | |
581 next_state_ = STATE_CTRL_INIT_COMPLETE; | |
582 return OK; | |
583 } | |
584 | |
585 int FtpNetworkTransaction::DoCtrlInitComplete(int result) { | |
586 next_state_ = STATE_CTRL_RESOLVE_HOST; | |
587 return OK; | |
588 } | |
589 | |
590 int FtpNetworkTransaction::DoCtrlResolveHost() { | 565 int FtpNetworkTransaction::DoCtrlResolveHost() { |
591 next_state_ = STATE_CTRL_RESOLVE_HOST_COMPLETE; | 566 next_state_ = STATE_CTRL_RESOLVE_HOST_COMPLETE; |
592 | 567 |
593 std::string host; | 568 std::string host; |
594 int port; | 569 int port; |
595 | 570 |
596 host = request_->url.HostNoBrackets(); | 571 host = request_->url.HostNoBrackets(); |
597 port = request_->url.EffectiveIntPort(); | 572 port = request_->url.EffectiveIntPort(); |
598 | 573 |
599 HostResolver::RequestInfo info(host, port); | 574 HostResolver::RequestInfo info(host, port); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 return SendFtpCommand(command, COMMAND_PASS); | 696 return SendFtpCommand(command, COMMAND_PASS); |
722 } | 697 } |
723 | 698 |
724 int FtpNetworkTransaction::ProcessResponsePASS( | 699 int FtpNetworkTransaction::ProcessResponsePASS( |
725 const FtpCtrlResponse& response) { | 700 const FtpCtrlResponse& response) { |
726 switch (GetErrorClass(response.status_code)) { | 701 switch (GetErrorClass(response.status_code)) { |
727 case ERROR_CLASS_OK: | 702 case ERROR_CLASS_OK: |
728 next_state_ = STATE_CTRL_WRITE_SYST; | 703 next_state_ = STATE_CTRL_WRITE_SYST; |
729 break; | 704 break; |
730 case ERROR_CLASS_INFO_NEEDED: | 705 case ERROR_CLASS_INFO_NEEDED: |
731 next_state_ = STATE_CTRL_WRITE_ACCT; | 706 return Stop(ERR_FAILED); |
732 break; | |
733 case ERROR_CLASS_TRANSIENT_ERROR: | 707 case ERROR_CLASS_TRANSIENT_ERROR: |
734 return Stop(ERR_FAILED); | 708 return Stop(ERR_FAILED); |
735 case ERROR_CLASS_PERMANENT_ERROR: | 709 case ERROR_CLASS_PERMANENT_ERROR: |
736 response_.needs_auth = true; | 710 response_.needs_auth = true; |
737 return Stop(ERR_FAILED); | 711 return Stop(ERR_FAILED); |
738 default: | 712 default: |
739 NOTREACHED(); | 713 NOTREACHED(); |
740 return Stop(ERR_UNEXPECTED); | 714 return Stop(ERR_UNEXPECTED); |
741 } | 715 } |
742 return OK; | 716 return OK; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 return Stop(ERR_FAILED); | 843 return Stop(ERR_FAILED); |
870 case ERROR_CLASS_PERMANENT_ERROR: | 844 case ERROR_CLASS_PERMANENT_ERROR: |
871 return Stop(ERR_FAILED); | 845 return Stop(ERR_FAILED); |
872 default: | 846 default: |
873 NOTREACHED(); | 847 NOTREACHED(); |
874 return Stop(ERR_UNEXPECTED); | 848 return Stop(ERR_UNEXPECTED); |
875 } | 849 } |
876 return OK; | 850 return OK; |
877 } | 851 } |
878 | 852 |
879 // ACCT command. | |
880 int FtpNetworkTransaction::DoCtrlWriteACCT() { | |
881 std::string command = "ACCT noaccount"; | |
882 next_state_ = STATE_CTRL_READ; | |
883 return SendFtpCommand(command, COMMAND_ACCT); | |
884 } | |
885 | |
886 int FtpNetworkTransaction::ProcessResponseACCT( | |
887 const FtpCtrlResponse& response) { | |
888 switch (GetErrorClass(response.status_code)) { | |
889 case ERROR_CLASS_INITIATED: | |
890 return Stop(ERR_INVALID_RESPONSE); | |
891 case ERROR_CLASS_OK: | |
892 next_state_ = STATE_CTRL_WRITE_SYST; | |
893 break; | |
894 case ERROR_CLASS_INFO_NEEDED: | |
895 return Stop(ERR_INVALID_RESPONSE); | |
896 case ERROR_CLASS_TRANSIENT_ERROR: | |
897 return Stop(ERR_FAILED); | |
898 case ERROR_CLASS_PERMANENT_ERROR: | |
899 return Stop(ERR_FAILED); | |
900 default: | |
901 NOTREACHED(); | |
902 return Stop(ERR_UNEXPECTED); | |
903 } | |
904 return OK; | |
905 } | |
906 | |
907 // EPSV command | 853 // EPSV command |
908 int FtpNetworkTransaction::DoCtrlWriteEPSV() { | 854 int FtpNetworkTransaction::DoCtrlWriteEPSV() { |
909 const std::string command = "EPSV"; | 855 const std::string command = "EPSV"; |
910 next_state_ = STATE_CTRL_READ; | 856 next_state_ = STATE_CTRL_READ; |
911 return SendFtpCommand(command, COMMAND_EPSV); | 857 return SendFtpCommand(command, COMMAND_EPSV); |
912 } | 858 } |
913 | 859 |
914 int FtpNetworkTransaction::ProcessResponseEPSV( | 860 int FtpNetworkTransaction::ProcessResponseEPSV( |
915 const FtpCtrlResponse& response) { | 861 const FtpCtrlResponse& response) { |
916 switch (GetErrorClass(response.status_code)) { | 862 switch (GetErrorClass(response.status_code)) { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 case ERROR_CLASS_INITIATED: | 978 case ERROR_CLASS_INITIATED: |
1033 // We want the client to start reading the response at this point. | 979 // We want the client to start reading the response at this point. |
1034 // It got here either through Start or RestartWithAuth. We want that | 980 // It got here either through Start or RestartWithAuth. We want that |
1035 // method to complete. Not setting next state here will make DoLoop exit | 981 // method to complete. Not setting next state here will make DoLoop exit |
1036 // and in turn make Start/RestartWithAuth complete. | 982 // and in turn make Start/RestartWithAuth complete. |
1037 break; | 983 break; |
1038 case ERROR_CLASS_OK: | 984 case ERROR_CLASS_OK: |
1039 next_state_ = STATE_CTRL_WRITE_QUIT; | 985 next_state_ = STATE_CTRL_WRITE_QUIT; |
1040 break; | 986 break; |
1041 case ERROR_CLASS_INFO_NEEDED: | 987 case ERROR_CLASS_INFO_NEEDED: |
1042 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; | 988 return Stop(ERR_FAILED); |
1043 break; | |
1044 case ERROR_CLASS_TRANSIENT_ERROR: | 989 case ERROR_CLASS_TRANSIENT_ERROR: |
1045 if (response.status_code == 421 || response.status_code == 425 || | 990 return Stop(ERR_FAILED); |
1046 response.status_code == 426) | |
1047 return Stop(ERR_FAILED); | |
1048 return ERR_FAILED; // TODO(ibrar): Retry here. | |
1049 case ERROR_CLASS_PERMANENT_ERROR: | 991 case ERROR_CLASS_PERMANENT_ERROR: |
1050 // Code 550 means "Failed to open file". Other codes are unrelated, | 992 // Code 550 means "Failed to open file". Other codes are unrelated, |
1051 // like "Not logged in" etc. | 993 // like "Not logged in" etc. |
1052 if (response.status_code != 550) | 994 if (response.status_code != 550) |
1053 return Stop(ERR_FAILED); | 995 return Stop(ERR_FAILED); |
1054 | 996 |
1055 // It's possible that RETR failed because the path is a directory. | 997 // It's possible that RETR failed because the path is a directory. |
1056 resource_type_ = RESOURCE_TYPE_DIRECTORY; | 998 resource_type_ = RESOURCE_TYPE_DIRECTORY; |
1057 | 999 |
1058 // We're going to try CWD next, but first send a PASV one more time, | 1000 // We're going to try CWD next, but first send a PASV one more time, |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 if (!had_error_type[type]) { | 1258 if (!had_error_type[type]) { |
1317 had_error_type[type] = true; | 1259 had_error_type[type] = true; |
1318 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1260 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
1319 type, NUM_OF_NET_ERROR_TYPES); | 1261 type, NUM_OF_NET_ERROR_TYPES); |
1320 } | 1262 } |
1321 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1263 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
1322 type, NUM_OF_NET_ERROR_TYPES); | 1264 type, NUM_OF_NET_ERROR_TYPES); |
1323 } | 1265 } |
1324 | 1266 |
1325 } // namespace net | 1267 } // namespace net |
OLD | NEW |