| 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 |