| 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_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 } | 211 } |
| 212 | 212 |
| 213 } // namespace | 213 } // namespace |
| 214 | 214 |
| 215 FtpNetworkTransaction::FtpNetworkTransaction( | 215 FtpNetworkTransaction::FtpNetworkTransaction( |
| 216 HostResolver* resolver, | 216 HostResolver* resolver, |
| 217 ClientSocketFactory* socket_factory) | 217 ClientSocketFactory* socket_factory) |
| 218 : command_sent_(COMMAND_NONE), | 218 : command_sent_(COMMAND_NONE), |
| 219 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, | 219 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
| 220 base::Unretained(this))), | 220 base::Unretained(this))), |
| 221 request_(NULL), | 221 request_(nullptr), |
| 222 resolver_(resolver), | 222 resolver_(resolver), |
| 223 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), | 223 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), |
| 224 read_data_buf_len_(0), | 224 read_data_buf_len_(0), |
| 225 last_error_(OK), | 225 last_error_(OK), |
| 226 system_type_(SYSTEM_TYPE_UNKNOWN), | 226 system_type_(SYSTEM_TYPE_UNKNOWN), |
| 227 // Use image (binary) transfer by default. It should always work, | 227 // Use image (binary) transfer by default. It should always work, |
| 228 // whereas the ascii transfer may damage binary data. | 228 // whereas the ascii transfer may damage binary data. |
| 229 data_type_(DATA_TYPE_IMAGE), | 229 data_type_(DATA_TYPE_IMAGE), |
| 230 resource_type_(RESOURCE_TYPE_UNKNOWN), | 230 resource_type_(RESOURCE_TYPE_UNKNOWN), |
| 231 use_epsv_(true), | 231 use_epsv_(true), |
| 232 data_connection_port_(0), | 232 data_connection_port_(0), |
| 233 socket_factory_(socket_factory), | 233 socket_factory_(socket_factory), |
| 234 next_state_(STATE_NONE), | 234 next_state_(STATE_NONE), |
| 235 state_after_data_connect_complete_(STATE_NONE) { | 235 state_after_data_connect_complete_(STATE_NONE) {} |
| 236 } | |
| 237 | 236 |
| 238 FtpNetworkTransaction::~FtpNetworkTransaction() { | 237 FtpNetworkTransaction::~FtpNetworkTransaction() { |
| 239 } | 238 } |
| 240 | 239 |
| 241 int FtpNetworkTransaction::Stop(int error) { | 240 int FtpNetworkTransaction::Stop(int error) { |
| 242 if (command_sent_ == COMMAND_QUIT) | 241 if (command_sent_ == COMMAND_QUIT) { |
| 243 return error; | 242 if (error != ERR_EMPTY_RESPONSE) |
| 243 return error; |
| 244 |
| 245 // For empty responses, if this is propagating an error, then it will return |
| 246 // the error. If the error occurred during a QUIT command, then this will |
| 247 // return OK since there was no previous error. Some FTP servers are lazy |
| 248 // and do not bother responding to QUIT commands. |
| 249 // See https://crbug.com/633841 |
| 250 return last_error_; |
| 251 } |
| 244 | 252 |
| 245 next_state_ = STATE_CTRL_WRITE_QUIT; | 253 next_state_ = STATE_CTRL_WRITE_QUIT; |
| 246 last_error_ = error; | 254 last_error_ = error; |
| 247 return OK; | 255 return OK; |
| 248 } | 256 } |
| 249 | 257 |
| 250 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, | 258 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, |
| 251 const CompletionCallback& callback, | 259 const CompletionCallback& callback, |
| 252 const NetLogWithSource& net_log) { | 260 const NetLogWithSource& net_log) { |
| 253 net_log_ = net_log; | 261 net_log_ = net_log; |
| 254 request_ = request_info; | 262 request_ = request_info; |
| 255 | 263 |
| 256 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); | 264 ctrl_response_buffer_ = base::MakeUnique<FtpCtrlResponseBuffer>(net_log_); |
| 257 | 265 |
| 258 if (request_->url.has_username()) { | 266 if (request_->url.has_username()) { |
| 259 base::string16 username; | 267 base::string16 username; |
| 260 base::string16 password; | 268 base::string16 password; |
| 261 GetIdentityFromURL(request_->url, &username, &password); | 269 GetIdentityFromURL(request_->url, &username, &password); |
| 262 credentials_.Set(username, password); | 270 credentials_.Set(username, password); |
| 263 } else { | 271 } else { |
| 264 credentials_.Set(base::ASCIIToUTF16("anonymous"), | 272 credentials_.Set(base::ASCIIToUTF16("anonymous"), |
| 265 base::ASCIIToUTF16("chrome@example.com")); | 273 base::ASCIIToUTF16("chrome@example.com")); |
| 266 } | 274 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 340 |
| 333 uint64_t FtpNetworkTransaction::GetUploadProgress() const { | 341 uint64_t FtpNetworkTransaction::GetUploadProgress() const { |
| 334 return 0; | 342 return 0; |
| 335 } | 343 } |
| 336 | 344 |
| 337 void FtpNetworkTransaction::ResetStateForRestart() { | 345 void FtpNetworkTransaction::ResetStateForRestart() { |
| 338 command_sent_ = COMMAND_NONE; | 346 command_sent_ = COMMAND_NONE; |
| 339 user_callback_.Reset(); | 347 user_callback_.Reset(); |
| 340 response_ = FtpResponseInfo(); | 348 response_ = FtpResponseInfo(); |
| 341 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); | 349 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); |
| 342 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); | 350 ctrl_response_buffer_ = base::MakeUnique<FtpCtrlResponseBuffer>(net_log_); |
| 343 read_data_buf_ = NULL; | 351 read_data_buf_ = nullptr; |
| 344 read_data_buf_len_ = 0; | 352 read_data_buf_len_ = 0; |
| 345 if (write_buf_.get()) | 353 if (write_buf_.get()) |
| 346 write_buf_->SetOffset(0); | 354 write_buf_->SetOffset(0); |
| 347 last_error_ = OK; | 355 last_error_ = OK; |
| 348 data_connection_port_ = 0; | 356 data_connection_port_ = 0; |
| 349 ctrl_socket_.reset(); | 357 ctrl_socket_.reset(); |
| 350 data_socket_.reset(); | 358 data_socket_.reset(); |
| 351 next_state_ = STATE_NONE; | 359 next_state_ = STATE_NONE; |
| 352 state_after_data_connect_complete_ = STATE_NONE; | 360 state_after_data_connect_complete_ = STATE_NONE; |
| 353 } | 361 } |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 | 668 |
| 661 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { | 669 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { |
| 662 if (result == OK) | 670 if (result == OK) |
| 663 next_state_ = STATE_CTRL_CONNECT; | 671 next_state_ = STATE_CTRL_CONNECT; |
| 664 return result; | 672 return result; |
| 665 } | 673 } |
| 666 | 674 |
| 667 int FtpNetworkTransaction::DoCtrlConnect() { | 675 int FtpNetworkTransaction::DoCtrlConnect() { |
| 668 next_state_ = STATE_CTRL_CONNECT_COMPLETE; | 676 next_state_ = STATE_CTRL_CONNECT_COMPLETE; |
| 669 ctrl_socket_ = socket_factory_->CreateTransportClientSocket( | 677 ctrl_socket_ = socket_factory_->CreateTransportClientSocket( |
| 670 addresses_, NULL, net_log_.net_log(), net_log_.source()); | 678 addresses_, nullptr, net_log_.net_log(), net_log_.source()); |
| 671 net_log_.AddEvent( | 679 net_log_.AddEvent( |
| 672 NetLogEventType::FTP_CONTROL_CONNECTION, | 680 NetLogEventType::FTP_CONTROL_CONNECTION, |
| 673 ctrl_socket_->NetLog().source().ToEventParametersCallback()); | 681 ctrl_socket_->NetLog().source().ToEventParametersCallback()); |
| 674 return ctrl_socket_->Connect(io_callback_); | 682 return ctrl_socket_->Connect(io_callback_); |
| 675 } | 683 } |
| 676 | 684 |
| 677 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { | 685 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { |
| 678 if (result == OK) { | 686 if (result == OK) { |
| 679 // Put the peer's IP address and port into the response. | 687 // Put the peer's IP address and port into the response. |
| 680 IPEndPoint ip_endpoint; | 688 IPEndPoint ip_endpoint; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 write_buf_.get(), write_buf_->BytesRemaining(), io_callback_); | 741 write_buf_.get(), write_buf_->BytesRemaining(), io_callback_); |
| 734 } | 742 } |
| 735 | 743 |
| 736 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { | 744 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { |
| 737 if (result < 0) | 745 if (result < 0) |
| 738 return result; | 746 return result; |
| 739 | 747 |
| 740 write_buf_->DidConsume(result); | 748 write_buf_->DidConsume(result); |
| 741 if (write_buf_->BytesRemaining() == 0) { | 749 if (write_buf_->BytesRemaining() == 0) { |
| 742 // Clear the write buffer. | 750 // Clear the write buffer. |
| 743 write_buf_ = NULL; | 751 write_buf_ = nullptr; |
| 744 write_command_buf_ = NULL; | 752 write_command_buf_ = nullptr; |
| 745 | 753 |
| 746 next_state_ = STATE_CTRL_READ; | 754 next_state_ = STATE_CTRL_READ; |
| 747 } else { | 755 } else { |
| 748 next_state_ = STATE_CTRL_WRITE; | 756 next_state_ = STATE_CTRL_WRITE; |
| 749 } | 757 } |
| 750 return OK; | 758 return OK; |
| 751 } | 759 } |
| 752 | 760 |
| 753 // FTP Commands and responses | 761 // FTP Commands and responses |
| 754 | 762 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 IPEndPoint ip_endpoint; | 1221 IPEndPoint ip_endpoint; |
| 1214 AddressList data_address; | 1222 AddressList data_address; |
| 1215 // Connect to the same host as the control socket to prevent PASV port | 1223 // Connect to the same host as the control socket to prevent PASV port |
| 1216 // scanning attacks. | 1224 // scanning attacks. |
| 1217 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); | 1225 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); |
| 1218 if (rv != OK) | 1226 if (rv != OK) |
| 1219 return Stop(rv); | 1227 return Stop(rv); |
| 1220 data_address = AddressList::CreateFromIPAddress( | 1228 data_address = AddressList::CreateFromIPAddress( |
| 1221 ip_endpoint.address(), data_connection_port_); | 1229 ip_endpoint.address(), data_connection_port_); |
| 1222 data_socket_ = socket_factory_->CreateTransportClientSocket( | 1230 data_socket_ = socket_factory_->CreateTransportClientSocket( |
| 1223 data_address, NULL, net_log_.net_log(), net_log_.source()); | 1231 data_address, nullptr, net_log_.net_log(), net_log_.source()); |
| 1224 net_log_.AddEvent( | 1232 net_log_.AddEvent( |
| 1225 NetLogEventType::FTP_DATA_CONNECTION, | 1233 NetLogEventType::FTP_DATA_CONNECTION, |
| 1226 data_socket_->NetLog().source().ToEventParametersCallback()); | 1234 data_socket_->NetLog().source().ToEventParametersCallback()); |
| 1227 return data_socket_->Connect(io_callback_); | 1235 return data_socket_->Connect(io_callback_); |
| 1228 } | 1236 } |
| 1229 | 1237 |
| 1230 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1238 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
| 1231 if (result != OK && use_epsv_) { | 1239 if (result != OK && use_epsv_) { |
| 1232 // It's possible we hit a broken server, sadly. They can break in different | 1240 // It's possible we hit a broken server, sadly. They can break in different |
| 1233 // ways. Some time out, some reset a connection. Fall back to PASV. | 1241 // ways. Some time out, some reset a connection. Fall back to PASV. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1246 return Stop(result); | 1254 return Stop(result); |
| 1247 | 1255 |
| 1248 next_state_ = state_after_data_connect_complete_; | 1256 next_state_ = state_after_data_connect_complete_; |
| 1249 return OK; | 1257 return OK; |
| 1250 } | 1258 } |
| 1251 | 1259 |
| 1252 int FtpNetworkTransaction::DoDataRead() { | 1260 int FtpNetworkTransaction::DoDataRead() { |
| 1253 DCHECK(read_data_buf_.get()); | 1261 DCHECK(read_data_buf_.get()); |
| 1254 DCHECK_GT(read_data_buf_len_, 0); | 1262 DCHECK_GT(read_data_buf_len_, 0); |
| 1255 | 1263 |
| 1256 if (data_socket_ == NULL || !data_socket_->IsConnected()) { | 1264 if (!data_socket_ || !data_socket_->IsConnected()) { |
| 1257 // If we don't destroy the data socket completely, some servers will wait | 1265 // If we don't destroy the data socket completely, some servers will wait |
| 1258 // for us (http://crbug.com/21127). The half-closed TCP connection needs | 1266 // for us (http://crbug.com/21127). The half-closed TCP connection needs |
| 1259 // to be closed on our side too. | 1267 // to be closed on our side too. |
| 1260 data_socket_.reset(); | 1268 data_socket_.reset(); |
| 1261 | 1269 |
| 1262 if (ctrl_socket_->IsConnected()) { | 1270 if (ctrl_socket_->IsConnected()) { |
| 1263 // Wait for the server's response, we should get it before sending QUIT. | 1271 // Wait for the server's response, we should get it before sending QUIT. |
| 1264 next_state_ = STATE_CTRL_READ; | 1272 next_state_ = STATE_CTRL_READ; |
| 1265 return OK; | 1273 return OK; |
| 1266 } | 1274 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 if (!had_error_type[type]) { | 1369 if (!had_error_type[type]) { |
| 1362 had_error_type[type] = true; | 1370 had_error_type[type] = true; |
| 1363 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1371 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
| 1364 type, NUM_OF_NET_ERROR_TYPES); | 1372 type, NUM_OF_NET_ERROR_TYPES); |
| 1365 } | 1373 } |
| 1366 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1374 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
| 1367 type, NUM_OF_NET_ERROR_TYPES); | 1375 type, NUM_OF_NET_ERROR_TYPES); |
| 1368 } | 1376 } |
| 1369 | 1377 |
| 1370 } // namespace net | 1378 } // namespace net |
| OLD | NEW |