| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 last_error_(OK), | 216 last_error_(OK), |
| 217 system_type_(SYSTEM_TYPE_UNKNOWN), | 217 system_type_(SYSTEM_TYPE_UNKNOWN), |
| 218 // Use image (binary) transfer by default. It should always work, | 218 // Use image (binary) transfer by default. It should always work, |
| 219 // whereas the ascii transfer may damage binary data. | 219 // whereas the ascii transfer may damage binary data. |
| 220 data_type_(DATA_TYPE_IMAGE), | 220 data_type_(DATA_TYPE_IMAGE), |
| 221 resource_type_(RESOURCE_TYPE_UNKNOWN), | 221 resource_type_(RESOURCE_TYPE_UNKNOWN), |
| 222 use_epsv_(true), | 222 use_epsv_(true), |
| 223 data_connection_port_(0), | 223 data_connection_port_(0), |
| 224 socket_factory_(socket_factory), | 224 socket_factory_(socket_factory), |
| 225 next_state_(STATE_NONE), | 225 next_state_(STATE_NONE), |
| 226 state_after_data_connect_complete_(STATE_CTRL_WRITE_SIZE) {} | 226 state_after_data_connect_complete_(STATE_CTRL_WRITE_SIZE) { |
| 227 } |
| 227 | 228 |
| 228 FtpNetworkTransaction::~FtpNetworkTransaction() { | 229 FtpNetworkTransaction::~FtpNetworkTransaction() { |
| 229 } | 230 } |
| 230 | 231 |
| 231 int FtpNetworkTransaction::Stop(int error) { | 232 int FtpNetworkTransaction::Stop(int error) { |
| 232 if (command_sent_ == COMMAND_QUIT) | 233 if (command_sent_ == COMMAND_QUIT) |
| 233 return error; | 234 return error; |
| 234 | 235 |
| 235 next_state_ = STATE_CTRL_WRITE_QUIT; | 236 next_state_ = STATE_CTRL_WRITE_QUIT; |
| 236 last_error_ = error; | 237 last_error_ = error; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 std::string::size_type pos = gurl_path.rfind(';'); | 493 std::string::size_type pos = gurl_path.rfind(';'); |
| 493 if (pos != std::string::npos) | 494 if (pos != std::string::npos) |
| 494 gurl_path.resize(pos); | 495 gurl_path.resize(pos); |
| 495 | 496 |
| 496 path.append(gurl_path); | 497 path.append(gurl_path); |
| 497 } | 498 } |
| 498 // Make sure that if the path is expected to be a file, it won't end | 499 // Make sure that if the path is expected to be a file, it won't end |
| 499 // with a trailing slash. | 500 // with a trailing slash. |
| 500 if (!is_directory && path.length() > 1 && path[path.length() - 1] == '/') | 501 if (!is_directory && path.length() > 1 && path[path.length() - 1] == '/') |
| 501 path.erase(path.length() - 1); | 502 path.erase(path.length() - 1); |
| 502 UnescapeRule::Type unescape_rules = UnescapeRule::SPACES | | 503 UnescapeRule::Type unescape_rules = |
| 503 UnescapeRule::URL_SPECIAL_CHARS; | 504 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS; |
| 504 // This may unescape to non-ASCII characters, but we allow that. See the | 505 // This may unescape to non-ASCII characters, but we allow that. See the |
| 505 // comment for IsValidFTPCommandString. | 506 // comment for IsValidFTPCommandString. |
| 506 path = net::UnescapeURLComponent(path, unescape_rules); | 507 path = net::UnescapeURLComponent(path, unescape_rules); |
| 507 | 508 |
| 508 if (system_type_ == SYSTEM_TYPE_VMS) { | 509 if (system_type_ == SYSTEM_TYPE_VMS) { |
| 509 if (is_directory) | 510 if (is_directory) |
| 510 path = FtpUtil::UnixDirectoryPathToVMS(path); | 511 path = FtpUtil::UnixDirectoryPathToVMS(path); |
| 511 else | 512 else |
| 512 path = FtpUtil::UnixFilePathToVMS(path); | 513 path = FtpUtil::UnixFilePathToVMS(path); |
| 513 } | 514 } |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 next_state_ = STATE_CTRL_READ; | 960 next_state_ = STATE_CTRL_READ; |
| 960 return SendFtpCommand(command, command, COMMAND_EPSV); | 961 return SendFtpCommand(command, command, COMMAND_EPSV); |
| 961 } | 962 } |
| 962 | 963 |
| 963 int FtpNetworkTransaction::ProcessResponseEPSV( | 964 int FtpNetworkTransaction::ProcessResponseEPSV( |
| 964 const FtpCtrlResponse& response) { | 965 const FtpCtrlResponse& response) { |
| 965 switch (GetErrorClass(response.status_code)) { | 966 switch (GetErrorClass(response.status_code)) { |
| 966 case ERROR_CLASS_INITIATED: | 967 case ERROR_CLASS_INITIATED: |
| 967 return Stop(ERR_INVALID_RESPONSE); | 968 return Stop(ERR_INVALID_RESPONSE); |
| 968 case ERROR_CLASS_OK: | 969 case ERROR_CLASS_OK: |
| 969 if (!ExtractPortFromEPSVResponse( response, &data_connection_port_)) | 970 if (!ExtractPortFromEPSVResponse(response, &data_connection_port_)) |
| 970 return Stop(ERR_INVALID_RESPONSE); | 971 return Stop(ERR_INVALID_RESPONSE); |
| 971 if (data_connection_port_ < 1024 || | 972 if (data_connection_port_ < 1024 || |
| 972 !IsPortAllowedByFtp(data_connection_port_)) | 973 !IsPortAllowedByFtp(data_connection_port_)) |
| 973 return Stop(ERR_UNSAFE_PORT); | 974 return Stop(ERR_UNSAFE_PORT); |
| 974 next_state_ = STATE_DATA_CONNECT; | 975 next_state_ = STATE_DATA_CONNECT; |
| 975 break; | 976 break; |
| 976 case ERROR_CLASS_INFO_NEEDED: | 977 case ERROR_CLASS_INFO_NEEDED: |
| 977 return Stop(ERR_INVALID_RESPONSE); | 978 return Stop(ERR_INVALID_RESPONSE); |
| 978 case ERROR_CLASS_TRANSIENT_ERROR: | 979 case ERROR_CLASS_TRANSIENT_ERROR: |
| 979 case ERROR_CLASS_PERMANENT_ERROR: | 980 case ERROR_CLASS_PERMANENT_ERROR: |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 | 1243 |
| 1243 int FtpNetworkTransaction::DoDataConnect() { | 1244 int FtpNetworkTransaction::DoDataConnect() { |
| 1244 next_state_ = STATE_DATA_CONNECT_COMPLETE; | 1245 next_state_ = STATE_DATA_CONNECT_COMPLETE; |
| 1245 IPEndPoint ip_endpoint; | 1246 IPEndPoint ip_endpoint; |
| 1246 AddressList data_address; | 1247 AddressList data_address; |
| 1247 // Connect to the same host as the control socket to prevent PASV port | 1248 // Connect to the same host as the control socket to prevent PASV port |
| 1248 // scanning attacks. | 1249 // scanning attacks. |
| 1249 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); | 1250 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); |
| 1250 if (rv != OK) | 1251 if (rv != OK) |
| 1251 return Stop(rv); | 1252 return Stop(rv); |
| 1252 data_address = AddressList::CreateFromIPAddress( | 1253 data_address = AddressList::CreateFromIPAddress(ip_endpoint.address(), |
| 1253 ip_endpoint.address(), data_connection_port_); | 1254 data_connection_port_); |
| 1254 data_socket_ = socket_factory_->CreateTransportClientSocket( | 1255 data_socket_ = socket_factory_->CreateTransportClientSocket( |
| 1255 data_address, net_log_.net_log(), net_log_.source()); | 1256 data_address, net_log_.net_log(), net_log_.source()); |
| 1256 net_log_.AddEvent( | 1257 net_log_.AddEvent( |
| 1257 NetLog::TYPE_FTP_DATA_CONNECTION, | 1258 NetLog::TYPE_FTP_DATA_CONNECTION, |
| 1258 data_socket_->NetLog().source().ToEventParametersCallback()); | 1259 data_socket_->NetLog().source().ToEventParametersCallback()); |
| 1259 return data_socket_->Connect(io_callback_); | 1260 return data_socket_->Connect(io_callback_); |
| 1260 } | 1261 } |
| 1261 | 1262 |
| 1262 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1263 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
| 1263 if (result != OK && use_epsv_) { | 1264 if (result != OK && use_epsv_) { |
| 1264 // It's possible we hit a broken server, sadly. They can break in different | 1265 // It's possible we hit a broken server, sadly. They can break in different |
| 1265 // ways. Some time out, some reset a connection. Fall back to PASV. | 1266 // ways. Some time out, some reset a connection. Fall back to PASV. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 NET_ERROR_INTERNET_DISCONNECTED = 5, | 1344 NET_ERROR_INTERNET_DISCONNECTED = 5, |
| 1344 | 1345 |
| 1345 // Could not reach the destination address. | 1346 // Could not reach the destination address. |
| 1346 NET_ERROR_ADDRESS_UNREACHABLE = 6, | 1347 NET_ERROR_ADDRESS_UNREACHABLE = 6, |
| 1347 | 1348 |
| 1348 // A programming error in our network stack. | 1349 // A programming error in our network stack. |
| 1349 NET_ERROR_UNEXPECTED = 7, | 1350 NET_ERROR_UNEXPECTED = 7, |
| 1350 | 1351 |
| 1351 // Other kind of error. | 1352 // Other kind of error. |
| 1352 NET_ERROR_OTHER = 20, | 1353 NET_ERROR_OTHER = 20, |
| 1353 | |
| 1354 NUM_OF_NET_ERROR_TYPES | 1354 NUM_OF_NET_ERROR_TYPES |
| 1355 } type; | 1355 } type; |
| 1356 switch (result) { | 1356 switch (result) { |
| 1357 case OK: | 1357 case OK: |
| 1358 type = NET_ERROR_OK; | 1358 type = NET_ERROR_OK; |
| 1359 break; | 1359 break; |
| 1360 case ERR_ACCESS_DENIED: | 1360 case ERR_ACCESS_DENIED: |
| 1361 case ERR_NETWORK_ACCESS_DENIED: | 1361 case ERR_NETWORK_ACCESS_DENIED: |
| 1362 type = NET_ERROR_ACCESS_DENIED; | 1362 type = NET_ERROR_ACCESS_DENIED; |
| 1363 break; | 1363 break; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1385 break; | 1385 break; |
| 1386 default: | 1386 default: |
| 1387 type = NET_ERROR_OTHER; | 1387 type = NET_ERROR_OTHER; |
| 1388 break; | 1388 break; |
| 1389 }; | 1389 }; |
| 1390 static bool had_error_type[NUM_OF_NET_ERROR_TYPES]; | 1390 static bool had_error_type[NUM_OF_NET_ERROR_TYPES]; |
| 1391 | 1391 |
| 1392 DCHECK(type >= 0 && type < NUM_OF_NET_ERROR_TYPES); | 1392 DCHECK(type >= 0 && type < NUM_OF_NET_ERROR_TYPES); |
| 1393 if (!had_error_type[type]) { | 1393 if (!had_error_type[type]) { |
| 1394 had_error_type[type] = true; | 1394 had_error_type[type] = true; |
| 1395 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1395 UMA_HISTOGRAM_ENUMERATION( |
| 1396 type, NUM_OF_NET_ERROR_TYPES); | 1396 "Net.FtpDataConnectionErrorHappened", type, NUM_OF_NET_ERROR_TYPES); |
| 1397 } | 1397 } |
| 1398 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1398 UMA_HISTOGRAM_ENUMERATION( |
| 1399 type, NUM_OF_NET_ERROR_TYPES); | 1399 "Net.FtpDataConnectionErrorCount", type, NUM_OF_NET_ERROR_TYPES); |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 } // namespace net | 1402 } // namespace net |
| OLD | NEW |