Chromium Code Reviews| 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 |