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. Use of this |
2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
3 // LICENSE file. | 3 // 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 break; | 327 break; |
328 case COMMAND_CWD: | 328 case COMMAND_CWD: |
329 rv = ProcessResponseCWD(response); | 329 rv = ProcessResponseCWD(response); |
330 break; | 330 break; |
331 case COMMAND_MLSD: | 331 case COMMAND_MLSD: |
332 rv = ProcessResponseMLSD(response); | 332 rv = ProcessResponseMLSD(response); |
333 break; | 333 break; |
334 case COMMAND_LIST: | 334 case COMMAND_LIST: |
335 rv = ProcessResponseLIST(response); | 335 rv = ProcessResponseLIST(response); |
336 break; | 336 break; |
337 case COMMAND_MDTM: | |
338 rv = ProcessResponseMDTM(response); | |
339 break; | |
340 case COMMAND_QUIT: | 337 case COMMAND_QUIT: |
341 rv = ProcessResponseQUIT(response); | 338 rv = ProcessResponseQUIT(response); |
342 break; | 339 break; |
343 default: | 340 default: |
344 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_; | 341 LOG(DFATAL) << "Unexpected value of command_sent_: " << command_sent_; |
345 return ERR_UNEXPECTED; | 342 return ERR_UNEXPECTED; |
346 } | 343 } |
347 | 344 |
348 // We may get multiple responses for some commands, | 345 // We may get multiple responses for some commands, |
349 // see http://crbug.com/18036. | 346 // see http://crbug.com/18036. |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 rv = DoCtrlWriteCWD(); | 542 rv = DoCtrlWriteCWD(); |
546 break; | 543 break; |
547 case STATE_CTRL_WRITE_MLSD: | 544 case STATE_CTRL_WRITE_MLSD: |
548 DCHECK(rv == 0); | 545 DCHECK(rv == 0); |
549 rv = DoCtrlWriteMLSD(); | 546 rv = DoCtrlWriteMLSD(); |
550 break; | 547 break; |
551 case STATE_CTRL_WRITE_LIST: | 548 case STATE_CTRL_WRITE_LIST: |
552 DCHECK(rv == OK); | 549 DCHECK(rv == OK); |
553 rv = DoCtrlWriteLIST(); | 550 rv = DoCtrlWriteLIST(); |
554 break; | 551 break; |
555 case STATE_CTRL_WRITE_MDTM: | |
556 DCHECK(rv == OK); | |
557 rv = DoCtrlWriteMDTM(); | |
558 break; | |
559 case STATE_CTRL_WRITE_QUIT: | 552 case STATE_CTRL_WRITE_QUIT: |
560 DCHECK(rv == OK); | 553 DCHECK(rv == OK); |
561 rv = DoCtrlWriteQUIT(); | 554 rv = DoCtrlWriteQUIT(); |
562 break; | 555 break; |
563 case STATE_DATA_CONNECT: | 556 case STATE_DATA_CONNECT: |
564 DCHECK(rv == OK); | 557 DCHECK(rv == OK); |
565 rv = DoDataConnect(); | 558 rv = DoDataConnect(); |
566 break; | 559 break; |
567 case STATE_DATA_CONNECT_COMPLETE: | 560 case STATE_DATA_CONNECT_COMPLETE: |
568 rv = DoDataConnectComplete(rv); | 561 rv = DoDataConnectComplete(rv); |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
998 return Stop(ERR_INVALID_RESPONSE); | 991 return Stop(ERR_INVALID_RESPONSE); |
999 if (size < 0) | 992 if (size < 0) |
1000 return Stop(ERR_INVALID_RESPONSE); | 993 return Stop(ERR_INVALID_RESPONSE); |
1001 response_.expected_content_size = size; | 994 response_.expected_content_size = size; |
1002 break; | 995 break; |
1003 case ERROR_CLASS_INFO_NEEDED: | 996 case ERROR_CLASS_INFO_NEEDED: |
1004 break; | 997 break; |
1005 case ERROR_CLASS_TRANSIENT_ERROR: | 998 case ERROR_CLASS_TRANSIENT_ERROR: |
1006 break; | 999 break; |
1007 case ERROR_CLASS_PERMANENT_ERROR: | 1000 case ERROR_CLASS_PERMANENT_ERROR: |
1001 // It's possible that SIZE failed because the path is a directory. | |
1002 if (response.status_code == 550 && | |
1003 resource_type_ == RESOURCE_TYPE_UNKNOWN) { | |
1004 resource_type_ = RESOURCE_TYPE_DIRECTORY; | |
1005 } else if (resource_type_ != RESOURCE_TYPE_DIRECTORY) { | |
1006 return Stop(ERR_FAILED); | |
wtc
2010/07/07 23:52:46
Nit: Can we return a better error code than ERR_FA
| |
1007 } | |
1008 break; | 1008 break; |
1009 default: | 1009 default: |
1010 NOTREACHED(); | 1010 NOTREACHED(); |
1011 return Stop(ERR_UNEXPECTED); | 1011 return Stop(ERR_UNEXPECTED); |
1012 } | 1012 } |
1013 next_state_ = STATE_CTRL_WRITE_MDTM; | 1013 |
1014 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) | |
1015 next_state_ = STATE_CTRL_WRITE_CWD; | |
1016 else | |
1017 next_state_ = STATE_CTRL_WRITE_RETR; | |
1018 | |
1014 return OK; | 1019 return OK; |
1015 } | 1020 } |
1016 | 1021 |
1017 // RETR command | 1022 // RETR command |
1018 int FtpNetworkTransaction::DoCtrlWriteRETR() { | 1023 int FtpNetworkTransaction::DoCtrlWriteRETR() { |
1019 std::string command = "RETR " + GetRequestPathForFtpCommand(false); | 1024 std::string command = "RETR " + GetRequestPathForFtpCommand(false); |
1020 next_state_ = STATE_CTRL_READ; | 1025 next_state_ = STATE_CTRL_READ; |
1021 return SendFtpCommand(command, COMMAND_RETR); | 1026 return SendFtpCommand(command, COMMAND_RETR); |
1022 } | 1027 } |
1023 | 1028 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1055 // See http://crbug.com/25316. | 1060 // See http://crbug.com/25316. |
1056 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; | 1061 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; |
1057 break; | 1062 break; |
1058 default: | 1063 default: |
1059 NOTREACHED(); | 1064 NOTREACHED(); |
1060 return Stop(ERR_UNEXPECTED); | 1065 return Stop(ERR_UNEXPECTED); |
1061 } | 1066 } |
1062 return OK; | 1067 return OK; |
1063 } | 1068 } |
1064 | 1069 |
1065 // MDMT command | |
1066 int FtpNetworkTransaction::DoCtrlWriteMDTM() { | |
1067 std::string command = "MDTM " + GetRequestPathForFtpCommand(false); | |
1068 next_state_ = STATE_CTRL_READ; | |
1069 return SendFtpCommand(command, COMMAND_MDTM); | |
1070 } | |
1071 | |
1072 int FtpNetworkTransaction::ProcessResponseMDTM( | |
1073 const FtpCtrlResponse& response) { | |
1074 switch (GetErrorClass(response.status_code)) { | |
1075 case ERROR_CLASS_INITIATED: | |
1076 return Stop(ERR_FAILED); | |
1077 case ERROR_CLASS_OK: | |
1078 next_state_ = STATE_CTRL_WRITE_RETR; | |
1079 break; | |
1080 case ERROR_CLASS_INFO_NEEDED: | |
1081 return Stop(ERR_FAILED); | |
1082 case ERROR_CLASS_TRANSIENT_ERROR: | |
1083 return Stop(ERR_FAILED); | |
1084 case ERROR_CLASS_PERMANENT_ERROR: | |
1085 next_state_ = STATE_CTRL_WRITE_RETR; | |
1086 break; | |
1087 default: | |
1088 NOTREACHED(); | |
1089 return Stop(ERR_UNEXPECTED); | |
1090 } | |
1091 return OK; | |
1092 } | |
1093 | |
1094 | |
1095 // CWD command | 1070 // CWD command |
1096 int FtpNetworkTransaction::DoCtrlWriteCWD() { | 1071 int FtpNetworkTransaction::DoCtrlWriteCWD() { |
1097 std::string command = "CWD " + GetRequestPathForFtpCommand(true); | 1072 std::string command = "CWD " + GetRequestPathForFtpCommand(true); |
1098 next_state_ = STATE_CTRL_READ; | 1073 next_state_ = STATE_CTRL_READ; |
1099 return SendFtpCommand(command, COMMAND_CWD); | 1074 return SendFtpCommand(command, COMMAND_CWD); |
1100 } | 1075 } |
1101 | 1076 |
1102 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { | 1077 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { |
1103 switch (GetErrorClass(response.status_code)) { | 1078 switch (GetErrorClass(response.status_code)) { |
1104 case ERROR_CLASS_INITIATED: | 1079 case ERROR_CLASS_INITIATED: |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1219 if (rv != OK) | 1194 if (rv != OK) |
1220 return Stop(rv); | 1195 return Stop(rv); |
1221 data_address.SetPort(data_connection_port_); | 1196 data_address.SetPort(data_connection_port_); |
1222 data_socket_.reset(socket_factory_->CreateTCPClientSocket( | 1197 data_socket_.reset(socket_factory_->CreateTCPClientSocket( |
1223 data_address, net_log_.net_log())); | 1198 data_address, net_log_.net_log())); |
1224 return data_socket_->Connect(&io_callback_); | 1199 return data_socket_->Connect(&io_callback_); |
1225 } | 1200 } |
1226 | 1201 |
1227 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1202 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
1228 RecordDataConnectionError(result); | 1203 RecordDataConnectionError(result); |
1229 if (resource_type_ == RESOURCE_TYPE_DIRECTORY) { | 1204 next_state_ = STATE_CTRL_WRITE_SIZE; |
1230 next_state_ = STATE_CTRL_WRITE_CWD; | |
1231 } else { | |
1232 next_state_ = STATE_CTRL_WRITE_SIZE; | |
1233 } | |
1234 return OK; | 1205 return OK; |
1235 } | 1206 } |
1236 | 1207 |
1237 int FtpNetworkTransaction::DoDataRead() { | 1208 int FtpNetworkTransaction::DoDataRead() { |
1238 DCHECK(read_data_buf_); | 1209 DCHECK(read_data_buf_); |
1239 DCHECK_GT(read_data_buf_len_, 0); | 1210 DCHECK_GT(read_data_buf_len_, 0); |
1240 | 1211 |
1241 if (data_socket_ == NULL || !data_socket_->IsConnected()) { | 1212 if (data_socket_ == NULL || !data_socket_->IsConnected()) { |
1242 // If we don't destroy the data socket completely, some servers will wait | 1213 // If we don't destroy the data socket completely, some servers will wait |
1243 // for us (http://crbug.com/21127). The half-closed TCP connection needs | 1214 // for us (http://crbug.com/21127). The half-closed TCP connection needs |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1345 if (!had_error_type[type]) { | 1316 if (!had_error_type[type]) { |
1346 had_error_type[type] = true; | 1317 had_error_type[type] = true; |
1347 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1318 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
1348 type, NUM_OF_NET_ERROR_TYPES); | 1319 type, NUM_OF_NET_ERROR_TYPES); |
1349 } | 1320 } |
1350 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1321 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
1351 type, NUM_OF_NET_ERROR_TYPES); | 1322 type, NUM_OF_NET_ERROR_TYPES); |
1352 } | 1323 } |
1353 | 1324 |
1354 } // namespace net | 1325 } // namespace net |
OLD | NEW |