Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: net/ftp/ftp_network_transaction.cc

Issue 2985012: FTP: add more detailed error codes based on RFC 959. (Closed)
Patch Set: fixes Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the 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"
(...skipping 25 matching lines...) Expand all
36 // characters in the command if the request path contains them. To be 36 // characters in the command if the request path contains them. To be
37 // compatible, we do the same and allow non-ASCII characters in a command. 37 // compatible, we do the same and allow non-ASCII characters in a command.
38 38
39 // Protect agains newline injection attack. 39 // Protect agains newline injection attack.
40 if (input.find_first_of("\r\n") != std::string::npos) 40 if (input.find_first_of("\r\n") != std::string::npos)
41 return false; 41 return false;
42 42
43 return true; 43 return true;
44 } 44 }
45 45
46 enum ErrorClass {
47 // The requested action was initiated. The client should expect another
48 // reply before issuing the next command.
49 ERROR_CLASS_INITIATED,
50
51 // The requested action has been successfully completed.
52 ERROR_CLASS_OK,
53
54 // The command has been accepted, but to complete the operation, more
55 // information must be sent by the client.
56 ERROR_CLASS_INFO_NEEDED,
57
58 // The command was not accepted and the requested action did not take place.
59 // This condition is temporary, and the client is encouraged to restart the
60 // command sequence.
61 ERROR_CLASS_TRANSIENT_ERROR,
62
63 // The command was not accepted and the requested action did not take place.
64 // This condition is rather permanent, and the client is discouraged from
65 // repeating the exact request.
66 ERROR_CLASS_PERMANENT_ERROR,
67 };
68
69 // Returns the error class for given response code. Caller should ensure
70 // that |response_code| is in range 100-599.
71 ErrorClass GetErrorClass(int response_code) {
72 if (response_code >= 100 && response_code <= 199)
73 return ERROR_CLASS_INITIATED;
74
75 if (response_code >= 200 && response_code <= 299)
76 return ERROR_CLASS_OK;
77
78 if (response_code >= 300 && response_code <= 399)
79 return ERROR_CLASS_INFO_NEEDED;
80
81 if (response_code >= 400 && response_code <= 499)
82 return ERROR_CLASS_TRANSIENT_ERROR;
83
84 if (response_code >= 500 && response_code <= 599)
85 return ERROR_CLASS_PERMANENT_ERROR;
86
87 // We should not be called on invalid error codes.
88 NOTREACHED() << response_code;
89 return ERROR_CLASS_PERMANENT_ERROR;
90 }
91
92 // Returns network error code for received FTP |response_code|.
93 int GetNetErrorCodeForFtpResponseCode(int response_code) {
94 switch (response_code) {
95 case 421:
96 return net::ERR_FTP_SERVICE_UNAVAILABLE;
97 case 426:
98 return net::ERR_FTP_TRANSFER_ABORTED;
99 case 450:
100 return net::ERR_FTP_FILE_BUSY;
101 case 500:
102 case 501:
103 return net::ERR_FTP_SYNTAX_ERROR;
104 case 502:
105 case 504:
106 return net::ERR_FTP_COMMAND_NOT_SUPPORTED;
107 case 503:
108 return net::ERR_FTP_BAD_COMMAND_SEQUENCE;
109 default:
110 return net::ERR_FTP_FAILED;
111 }
112 }
113
46 // From RFC 2428 Section 3: 114 // From RFC 2428 Section 3:
47 // The text returned in response to the EPSV command MUST be: 115 // The text returned in response to the EPSV command MUST be:
48 // <some text> (<d><d><d><tcp-port><d>) 116 // <some text> (<d><d><d><tcp-port><d>)
49 // <d> is a delimiter character, ideally to be | 117 // <d> is a delimiter character, ideally to be |
50 bool ExtractPortFromEPSVResponse(const net::FtpCtrlResponse& response, 118 bool ExtractPortFromEPSVResponse(const net::FtpCtrlResponse& response,
51 int* port) { 119 int* port) {
52 if (response.lines.size() != 1) 120 if (response.lines.size() != 1)
53 return false; 121 return false;
54 const char* ptr = response.lines[0].c_str(); 122 const char* ptr = response.lines[0].c_str();
55 while (*ptr && *ptr != '(') 123 while (*ptr && *ptr != '(')
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 244
177 next_state_ = STATE_CTRL_RESOLVE_HOST; 245 next_state_ = STATE_CTRL_RESOLVE_HOST;
178 int rv = DoLoop(OK); 246 int rv = DoLoop(OK);
179 if (rv == ERR_IO_PENDING) 247 if (rv == ERR_IO_PENDING)
180 user_callback_ = callback; 248 user_callback_ = callback;
181 return rv; 249 return rv;
182 } 250 }
183 251
184 int FtpNetworkTransaction::RestartIgnoringLastError( 252 int FtpNetworkTransaction::RestartIgnoringLastError(
185 CompletionCallback* callback) { 253 CompletionCallback* callback) {
186 return ERR_FAILED; 254 return ERR_NOT_IMPLEMENTED;
187 } 255 }
188 256
189 int FtpNetworkTransaction::Read(IOBuffer* buf, 257 int FtpNetworkTransaction::Read(IOBuffer* buf,
190 int buf_len, 258 int buf_len,
191 CompletionCallback* callback) { 259 CompletionCallback* callback) {
192 DCHECK(buf); 260 DCHECK(buf);
193 DCHECK_GT(buf_len, 0); 261 DCHECK_GT(buf_len, 0);
194 262
195 read_data_buf_ = buf; 263 read_data_buf_ = buf;
196 read_data_buf_len_ = buf_len; 264 read_data_buf_len_ = buf_len;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 write_command_buf_ = new IOBufferWithSize(command.length() + 2); 324 write_command_buf_ = new IOBufferWithSize(command.length() + 2);
257 write_buf_ = new DrainableIOBuffer(write_command_buf_, 325 write_buf_ = new DrainableIOBuffer(write_command_buf_,
258 write_command_buf_->size()); 326 write_command_buf_->size());
259 memcpy(write_command_buf_->data(), command.data(), command.length()); 327 memcpy(write_command_buf_->data(), command.data(), command.length());
260 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2); 328 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2);
261 329
262 next_state_ = STATE_CTRL_WRITE; 330 next_state_ = STATE_CTRL_WRITE;
263 return OK; 331 return OK;
264 } 332 }
265 333
266 // static
267 FtpNetworkTransaction::ErrorClass FtpNetworkTransaction::GetErrorClass(
268 int response_code) {
269 if (response_code >= 100 && response_code <= 199)
270 return ERROR_CLASS_INITIATED;
271
272 if (response_code >= 200 && response_code <= 299)
273 return ERROR_CLASS_OK;
274
275 if (response_code >= 300 && response_code <= 399)
276 return ERROR_CLASS_INFO_NEEDED;
277
278 if (response_code >= 400 && response_code <= 499)
279 return ERROR_CLASS_TRANSIENT_ERROR;
280
281 if (response_code >= 500 && response_code <= 599)
282 return ERROR_CLASS_PERMANENT_ERROR;
283
284 // We should not be called on invalid error codes.
285 NOTREACHED();
286 return ERROR_CLASS_PERMANENT_ERROR;
287 }
288
289 int FtpNetworkTransaction::ProcessCtrlResponse() { 334 int FtpNetworkTransaction::ProcessCtrlResponse() {
290 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse(); 335 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse();
291 336
292 int rv = OK; 337 int rv = OK;
293 switch (command_sent_) { 338 switch (command_sent_) {
294 case COMMAND_NONE: 339 case COMMAND_NONE:
295 // TODO(phajdan.jr): Check for errors in the welcome message. 340 // TODO(phajdan.jr): Check for errors in the welcome message.
296 next_state_ = STATE_CTRL_WRITE_USER; 341 next_state_ = STATE_CTRL_WRITE_USER;
297 break; 342 break;
298 case COMMAND_USER: 343 case COMMAND_USER:
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 int FtpNetworkTransaction::ProcessResponseUSER( 712 int FtpNetworkTransaction::ProcessResponseUSER(
668 const FtpCtrlResponse& response) { 713 const FtpCtrlResponse& response) {
669 switch (GetErrorClass(response.status_code)) { 714 switch (GetErrorClass(response.status_code)) {
670 case ERROR_CLASS_OK: 715 case ERROR_CLASS_OK:
671 next_state_ = STATE_CTRL_WRITE_SYST; 716 next_state_ = STATE_CTRL_WRITE_SYST;
672 break; 717 break;
673 case ERROR_CLASS_INFO_NEEDED: 718 case ERROR_CLASS_INFO_NEEDED:
674 next_state_ = STATE_CTRL_WRITE_PASS; 719 next_state_ = STATE_CTRL_WRITE_PASS;
675 break; 720 break;
676 case ERROR_CLASS_TRANSIENT_ERROR: 721 case ERROR_CLASS_TRANSIENT_ERROR:
677 return Stop(ERR_FAILED); 722 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
678 case ERROR_CLASS_PERMANENT_ERROR: 723 case ERROR_CLASS_PERMANENT_ERROR:
679 response_.needs_auth = true; 724 response_.needs_auth = true;
680 return Stop(ERR_FAILED); 725 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
681 default: 726 default:
682 NOTREACHED(); 727 NOTREACHED();
683 return Stop(ERR_UNEXPECTED); 728 return Stop(ERR_UNEXPECTED);
684 } 729 }
685 return OK; 730 return OK;
686 } 731 }
687 732
688 // PASS command. 733 // PASS command.
689 int FtpNetworkTransaction::DoCtrlWritePASS() { 734 int FtpNetworkTransaction::DoCtrlWritePASS() {
690 std::string command = "PASS " + WideToUTF8(password_); 735 std::string command = "PASS " + WideToUTF8(password_);
691 736
692 if (!IsValidFTPCommandString(command)) 737 if (!IsValidFTPCommandString(command))
693 return Stop(ERR_MALFORMED_IDENTITY); 738 return Stop(ERR_MALFORMED_IDENTITY);
694 739
695 next_state_ = STATE_CTRL_READ; 740 next_state_ = STATE_CTRL_READ;
696 return SendFtpCommand(command, COMMAND_PASS); 741 return SendFtpCommand(command, COMMAND_PASS);
697 } 742 }
698 743
699 int FtpNetworkTransaction::ProcessResponsePASS( 744 int FtpNetworkTransaction::ProcessResponsePASS(
700 const FtpCtrlResponse& response) { 745 const FtpCtrlResponse& response) {
701 switch (GetErrorClass(response.status_code)) { 746 switch (GetErrorClass(response.status_code)) {
702 case ERROR_CLASS_OK: 747 case ERROR_CLASS_OK:
703 next_state_ = STATE_CTRL_WRITE_SYST; 748 next_state_ = STATE_CTRL_WRITE_SYST;
704 break; 749 break;
705 case ERROR_CLASS_INFO_NEEDED: 750 case ERROR_CLASS_INFO_NEEDED:
706 return Stop(ERR_FAILED); 751 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
707 case ERROR_CLASS_TRANSIENT_ERROR: 752 case ERROR_CLASS_TRANSIENT_ERROR:
708 return Stop(ERR_FAILED); 753 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
709 case ERROR_CLASS_PERMANENT_ERROR: 754 case ERROR_CLASS_PERMANENT_ERROR:
710 response_.needs_auth = true; 755 response_.needs_auth = true;
711 return Stop(ERR_FAILED); 756 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
712 default: 757 default:
713 NOTREACHED(); 758 NOTREACHED();
714 return Stop(ERR_UNEXPECTED); 759 return Stop(ERR_UNEXPECTED);
715 } 760 }
716 return OK; 761 return OK;
717 } 762 }
718 763
719 // SYST command. 764 // SYST command.
720 int FtpNetworkTransaction::DoCtrlWriteSYST() { 765 int FtpNetworkTransaction::DoCtrlWriteSYST() {
721 std::string command = "SYST"; 766 std::string command = "SYST";
(...skipping 28 matching lines...) Expand all
750 } else if (line.find("vms") != std::string::npos) { 795 } else if (line.find("vms") != std::string::npos) {
751 system_type_ = SYSTEM_TYPE_VMS; 796 system_type_ = SYSTEM_TYPE_VMS;
752 } 797 }
753 } 798 }
754 next_state_ = STATE_CTRL_WRITE_PWD; 799 next_state_ = STATE_CTRL_WRITE_PWD;
755 break; 800 break;
756 } 801 }
757 case ERROR_CLASS_INFO_NEEDED: 802 case ERROR_CLASS_INFO_NEEDED:
758 return Stop(ERR_INVALID_RESPONSE); 803 return Stop(ERR_INVALID_RESPONSE);
759 case ERROR_CLASS_TRANSIENT_ERROR: 804 case ERROR_CLASS_TRANSIENT_ERROR:
760 return Stop(ERR_FAILED); 805 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
761 case ERROR_CLASS_PERMANENT_ERROR: 806 case ERROR_CLASS_PERMANENT_ERROR:
762 // Server does not recognize the SYST command so proceed. 807 // Server does not recognize the SYST command so proceed.
763 next_state_ = STATE_CTRL_WRITE_PWD; 808 next_state_ = STATE_CTRL_WRITE_PWD;
764 break; 809 break;
765 default: 810 default:
766 NOTREACHED(); 811 NOTREACHED();
767 return Stop(ERR_UNEXPECTED); 812 return Stop(ERR_UNEXPECTED);
768 } 813 }
769 return OK; 814 return OK;
770 } 815 }
(...skipping 26 matching lines...) Expand all
797 line = FtpUtil::VMSPathToUnix(line); 842 line = FtpUtil::VMSPathToUnix(line);
798 if (line.length() && line[line.length() - 1] == '/') 843 if (line.length() && line[line.length() - 1] == '/')
799 line.erase(line.length() - 1); 844 line.erase(line.length() - 1);
800 current_remote_directory_ = line; 845 current_remote_directory_ = line;
801 next_state_ = STATE_CTRL_WRITE_TYPE; 846 next_state_ = STATE_CTRL_WRITE_TYPE;
802 break; 847 break;
803 } 848 }
804 case ERROR_CLASS_INFO_NEEDED: 849 case ERROR_CLASS_INFO_NEEDED:
805 return Stop(ERR_INVALID_RESPONSE); 850 return Stop(ERR_INVALID_RESPONSE);
806 case ERROR_CLASS_TRANSIENT_ERROR: 851 case ERROR_CLASS_TRANSIENT_ERROR:
807 return Stop(ERR_FAILED); 852 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
808 case ERROR_CLASS_PERMANENT_ERROR: 853 case ERROR_CLASS_PERMANENT_ERROR:
809 return Stop(ERR_FAILED); 854 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
810 default: 855 default:
811 NOTREACHED(); 856 NOTREACHED();
812 return Stop(ERR_UNEXPECTED); 857 return Stop(ERR_UNEXPECTED);
813 } 858 }
814 return OK; 859 return OK;
815 } 860 }
816 861
817 // TYPE command. 862 // TYPE command.
818 int FtpNetworkTransaction::DoCtrlWriteTYPE() { 863 int FtpNetworkTransaction::DoCtrlWriteTYPE() {
819 std::string command = "TYPE "; 864 std::string command = "TYPE ";
(...skipping 13 matching lines...) Expand all
833 const FtpCtrlResponse& response) { 878 const FtpCtrlResponse& response) {
834 switch (GetErrorClass(response.status_code)) { 879 switch (GetErrorClass(response.status_code)) {
835 case ERROR_CLASS_INITIATED: 880 case ERROR_CLASS_INITIATED:
836 return Stop(ERR_INVALID_RESPONSE); 881 return Stop(ERR_INVALID_RESPONSE);
837 case ERROR_CLASS_OK: 882 case ERROR_CLASS_OK:
838 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; 883 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV;
839 break; 884 break;
840 case ERROR_CLASS_INFO_NEEDED: 885 case ERROR_CLASS_INFO_NEEDED:
841 return Stop(ERR_INVALID_RESPONSE); 886 return Stop(ERR_INVALID_RESPONSE);
842 case ERROR_CLASS_TRANSIENT_ERROR: 887 case ERROR_CLASS_TRANSIENT_ERROR:
843 return Stop(ERR_FAILED); 888 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
844 case ERROR_CLASS_PERMANENT_ERROR: 889 case ERROR_CLASS_PERMANENT_ERROR:
845 return Stop(ERR_FAILED); 890 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
846 default: 891 default:
847 NOTREACHED(); 892 NOTREACHED();
848 return Stop(ERR_UNEXPECTED); 893 return Stop(ERR_UNEXPECTED);
849 } 894 }
850 return OK; 895 return OK;
851 } 896 }
852 897
853 // EPSV command 898 // EPSV command
854 int FtpNetworkTransaction::DoCtrlWriteEPSV() { 899 int FtpNetworkTransaction::DoCtrlWriteEPSV() {
855 const std::string command = "EPSV"; 900 const std::string command = "EPSV";
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 if (!ExtractPortFromPASVResponse(response, &data_connection_port_)) 945 if (!ExtractPortFromPASVResponse(response, &data_connection_port_))
901 return Stop(ERR_INVALID_RESPONSE); 946 return Stop(ERR_INVALID_RESPONSE);
902 if (data_connection_port_ < 1024 || 947 if (data_connection_port_ < 1024 ||
903 !IsPortAllowedByFtp(data_connection_port_)) 948 !IsPortAllowedByFtp(data_connection_port_))
904 return Stop(ERR_UNSAFE_PORT); 949 return Stop(ERR_UNSAFE_PORT);
905 next_state_ = STATE_DATA_CONNECT; 950 next_state_ = STATE_DATA_CONNECT;
906 break; 951 break;
907 case ERROR_CLASS_INFO_NEEDED: 952 case ERROR_CLASS_INFO_NEEDED:
908 return Stop(ERR_INVALID_RESPONSE); 953 return Stop(ERR_INVALID_RESPONSE);
909 case ERROR_CLASS_TRANSIENT_ERROR: 954 case ERROR_CLASS_TRANSIENT_ERROR:
910 return Stop(ERR_FTP_PASV_COMMAND_FAILED); 955 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
911 case ERROR_CLASS_PERMANENT_ERROR: 956 case ERROR_CLASS_PERMANENT_ERROR:
912 return Stop(ERR_FTP_PASV_COMMAND_FAILED); 957 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
913 default: 958 default:
914 NOTREACHED(); 959 NOTREACHED();
915 return Stop(ERR_UNEXPECTED); 960 return Stop(ERR_UNEXPECTED);
916 } 961 }
917 return OK; 962 return OK;
918 } 963 }
919 964
920 // SIZE command 965 // SIZE command
921 int FtpNetworkTransaction::DoCtrlWriteSIZE() { 966 int FtpNetworkTransaction::DoCtrlWriteSIZE() {
922 std::string command = "SIZE " + GetRequestPathForFtpCommand(false); 967 std::string command = "SIZE " + GetRequestPathForFtpCommand(false);
(...skipping 19 matching lines...) Expand all
942 case ERROR_CLASS_INFO_NEEDED: 987 case ERROR_CLASS_INFO_NEEDED:
943 break; 988 break;
944 case ERROR_CLASS_TRANSIENT_ERROR: 989 case ERROR_CLASS_TRANSIENT_ERROR:
945 break; 990 break;
946 case ERROR_CLASS_PERMANENT_ERROR: 991 case ERROR_CLASS_PERMANENT_ERROR:
947 // It's possible that SIZE failed because the path is a directory. 992 // It's possible that SIZE failed because the path is a directory.
948 if (response.status_code == 550 && 993 if (response.status_code == 550 &&
949 resource_type_ == RESOURCE_TYPE_UNKNOWN) { 994 resource_type_ == RESOURCE_TYPE_UNKNOWN) {
950 resource_type_ = RESOURCE_TYPE_DIRECTORY; 995 resource_type_ = RESOURCE_TYPE_DIRECTORY;
951 } else if (resource_type_ != RESOURCE_TYPE_DIRECTORY) { 996 } else if (resource_type_ != RESOURCE_TYPE_DIRECTORY) {
952 return Stop(ERR_FAILED); 997 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
953 } 998 }
954 break; 999 break;
955 default: 1000 default:
956 NOTREACHED(); 1001 NOTREACHED();
957 return Stop(ERR_UNEXPECTED); 1002 return Stop(ERR_UNEXPECTED);
958 } 1003 }
959 1004
960 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) 1005 if (resource_type_ == RESOURCE_TYPE_DIRECTORY)
961 next_state_ = STATE_CTRL_WRITE_CWD; 1006 next_state_ = STATE_CTRL_WRITE_CWD;
962 else 1007 else
(...skipping 15 matching lines...) Expand all
978 case ERROR_CLASS_INITIATED: 1023 case ERROR_CLASS_INITIATED:
979 // We want the client to start reading the response at this point. 1024 // We want the client to start reading the response at this point.
980 // It got here either through Start or RestartWithAuth. We want that 1025 // It got here either through Start or RestartWithAuth. We want that
981 // method to complete. Not setting next state here will make DoLoop exit 1026 // method to complete. Not setting next state here will make DoLoop exit
982 // and in turn make Start/RestartWithAuth complete. 1027 // and in turn make Start/RestartWithAuth complete.
983 break; 1028 break;
984 case ERROR_CLASS_OK: 1029 case ERROR_CLASS_OK:
985 next_state_ = STATE_CTRL_WRITE_QUIT; 1030 next_state_ = STATE_CTRL_WRITE_QUIT;
986 break; 1031 break;
987 case ERROR_CLASS_INFO_NEEDED: 1032 case ERROR_CLASS_INFO_NEEDED:
988 return Stop(ERR_FAILED); 1033 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
989 case ERROR_CLASS_TRANSIENT_ERROR: 1034 case ERROR_CLASS_TRANSIENT_ERROR:
990 return Stop(ERR_FAILED); 1035 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
991 case ERROR_CLASS_PERMANENT_ERROR: 1036 case ERROR_CLASS_PERMANENT_ERROR:
992 // Code 550 means "Failed to open file". Other codes are unrelated, 1037 // Code 550 means "Failed to open file". Other codes are unrelated,
993 // like "Not logged in" etc. 1038 // like "Not logged in" etc.
994 if (response.status_code != 550) 1039 if (response.status_code != 550)
995 return Stop(ERR_FAILED); 1040 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
996 1041
997 // It's possible that RETR failed because the path is a directory. 1042 // It's possible that RETR failed because the path is a directory.
998 resource_type_ = RESOURCE_TYPE_DIRECTORY; 1043 resource_type_ = RESOURCE_TYPE_DIRECTORY;
999 1044
1000 // We're going to try CWD next, but first send a PASV one more time, 1045 // We're going to try CWD next, but first send a PASV one more time,
1001 // because some FTP servers, including FileZilla, require that. 1046 // because some FTP servers, including FileZilla, require that.
1002 // See http://crbug.com/25316. 1047 // See http://crbug.com/25316.
1003 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; 1048 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV;
1004 break; 1049 break;
1005 default: 1050 default:
(...skipping 13 matching lines...) Expand all
1019 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { 1064 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) {
1020 switch (GetErrorClass(response.status_code)) { 1065 switch (GetErrorClass(response.status_code)) {
1021 case ERROR_CLASS_INITIATED: 1066 case ERROR_CLASS_INITIATED:
1022 return Stop(ERR_INVALID_RESPONSE); 1067 return Stop(ERR_INVALID_RESPONSE);
1023 case ERROR_CLASS_OK: 1068 case ERROR_CLASS_OK:
1024 next_state_ = STATE_CTRL_WRITE_MLSD; 1069 next_state_ = STATE_CTRL_WRITE_MLSD;
1025 break; 1070 break;
1026 case ERROR_CLASS_INFO_NEEDED: 1071 case ERROR_CLASS_INFO_NEEDED:
1027 return Stop(ERR_INVALID_RESPONSE); 1072 return Stop(ERR_INVALID_RESPONSE);
1028 case ERROR_CLASS_TRANSIENT_ERROR: 1073 case ERROR_CLASS_TRANSIENT_ERROR:
1029 return Stop(ERR_FAILED); 1074 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1030 case ERROR_CLASS_PERMANENT_ERROR: 1075 case ERROR_CLASS_PERMANENT_ERROR:
1031 if (resource_type_ == RESOURCE_TYPE_DIRECTORY && 1076 if (resource_type_ == RESOURCE_TYPE_DIRECTORY &&
1032 response.status_code == 550) { 1077 response.status_code == 550) {
1033 // We're assuming that the resource is a directory, but the server says 1078 // We're assuming that the resource is a directory, but the server says
1034 // it's not true. The most probable interpretation is that it doesn't 1079 // it's not true. The most probable interpretation is that it doesn't
1035 // exist (with FTP we can't be sure). 1080 // exist (with FTP we can't be sure).
1036 return Stop(ERR_FILE_NOT_FOUND); 1081 return Stop(ERR_FILE_NOT_FOUND);
1037 } 1082 }
1038 return Stop(ERR_FAILED); 1083 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1039 default: 1084 default:
1040 NOTREACHED(); 1085 NOTREACHED();
1041 return Stop(ERR_UNEXPECTED); 1086 return Stop(ERR_UNEXPECTED);
1042 } 1087 }
1043 return OK; 1088 return OK;
1044 } 1089 }
1045 1090
1046 // MLSD command 1091 // MLSD command
1047 int FtpNetworkTransaction::DoCtrlWriteMLSD() { 1092 int FtpNetworkTransaction::DoCtrlWriteMLSD() {
1048 next_state_ = STATE_CTRL_READ; 1093 next_state_ = STATE_CTRL_READ;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 // and in turn make Start/RestartWithAuth complete. 1140 // and in turn make Start/RestartWithAuth complete.
1096 response_.is_directory_listing = true; 1141 response_.is_directory_listing = true;
1097 break; 1142 break;
1098 case ERROR_CLASS_OK: 1143 case ERROR_CLASS_OK:
1099 response_.is_directory_listing = true; 1144 response_.is_directory_listing = true;
1100 next_state_ = STATE_CTRL_WRITE_QUIT; 1145 next_state_ = STATE_CTRL_WRITE_QUIT;
1101 break; 1146 break;
1102 case ERROR_CLASS_INFO_NEEDED: 1147 case ERROR_CLASS_INFO_NEEDED:
1103 return Stop(ERR_INVALID_RESPONSE); 1148 return Stop(ERR_INVALID_RESPONSE);
1104 case ERROR_CLASS_TRANSIENT_ERROR: 1149 case ERROR_CLASS_TRANSIENT_ERROR:
1105 return Stop(ERR_FAILED); 1150 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1106 case ERROR_CLASS_PERMANENT_ERROR: 1151 case ERROR_CLASS_PERMANENT_ERROR:
1107 return Stop(ERR_FAILED); 1152 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
1108 default: 1153 default:
1109 NOTREACHED(); 1154 NOTREACHED();
1110 return Stop(ERR_UNEXPECTED); 1155 return Stop(ERR_UNEXPECTED);
1111 } 1156 }
1112 return OK; 1157 return OK;
1113 } 1158 }
1114 1159
1115 // QUIT command 1160 // QUIT command
1116 int FtpNetworkTransaction::DoCtrlWriteQUIT() { 1161 int FtpNetworkTransaction::DoCtrlWriteQUIT() {
1117 std::string command = "QUIT"; 1162 std::string command = "QUIT";
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 if (!had_error_type[type]) { 1303 if (!had_error_type[type]) {
1259 had_error_type[type] = true; 1304 had_error_type[type] = true;
1260 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", 1305 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened",
1261 type, NUM_OF_NET_ERROR_TYPES); 1306 type, NUM_OF_NET_ERROR_TYPES);
1262 } 1307 }
1263 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", 1308 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount",
1264 type, NUM_OF_NET_ERROR_TYPES); 1309 type, NUM_OF_NET_ERROR_TYPES);
1265 } 1310 }
1266 1311
1267 } // namespace net 1312 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698