| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 | 199 |
| 200 } // namespace | 200 } // namespace |
| 201 | 201 |
| 202 namespace net { | 202 namespace net { |
| 203 | 203 |
| 204 FtpNetworkTransaction::FtpNetworkTransaction( | 204 FtpNetworkTransaction::FtpNetworkTransaction( |
| 205 FtpNetworkSession* session, | 205 FtpNetworkSession* session, |
| 206 ClientSocketFactory* socket_factory) | 206 ClientSocketFactory* socket_factory) |
| 207 : command_sent_(COMMAND_NONE), | 207 : command_sent_(COMMAND_NONE), |
| 208 ALLOW_THIS_IN_INITIALIZER_LIST( | 208 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 209 io_callback_(this, &FtpNetworkTransaction::OnIOComplete)), | 209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
| 210 user_callback_(NULL), | 210 base::Unretained(this)))), |
| 211 session_(session), | 211 session_(session), |
| 212 request_(NULL), | 212 request_(NULL), |
| 213 resolver_(session->host_resolver()), | 213 resolver_(session->host_resolver()), |
| 214 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), | 214 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), |
| 215 ctrl_response_buffer_(new FtpCtrlResponseBuffer()), | 215 ctrl_response_buffer_(new FtpCtrlResponseBuffer()), |
| 216 read_data_buf_len_(0), | 216 read_data_buf_len_(0), |
| 217 last_error_(OK), | 217 last_error_(OK), |
| 218 system_type_(SYSTEM_TYPE_UNKNOWN), | 218 system_type_(SYSTEM_TYPE_UNKNOWN), |
| 219 // Use image (binary) transfer by default. It should always work, | 219 // Use image (binary) transfer by default. It should always work, |
| 220 // whereas the ascii transfer may damage binary data. | 220 // whereas the ascii transfer may damage binary data. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 232 int FtpNetworkTransaction::Stop(int error) { | 232 int FtpNetworkTransaction::Stop(int error) { |
| 233 if (command_sent_ == COMMAND_QUIT) | 233 if (command_sent_ == COMMAND_QUIT) |
| 234 return error; | 234 return error; |
| 235 | 235 |
| 236 next_state_ = STATE_CTRL_WRITE_QUIT; | 236 next_state_ = STATE_CTRL_WRITE_QUIT; |
| 237 last_error_ = error; | 237 last_error_ = error; |
| 238 return OK; | 238 return OK; |
| 239 } | 239 } |
| 240 | 240 |
| 241 int FtpNetworkTransaction::RestartIgnoringLastError( | 241 int FtpNetworkTransaction::RestartIgnoringLastError( |
| 242 OldCompletionCallback* callback) { | 242 const CompletionCallback& callback) { |
| 243 return ERR_NOT_IMPLEMENTED; | 243 return ERR_NOT_IMPLEMENTED; |
| 244 } | 244 } |
| 245 | 245 |
| 246 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, | 246 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, |
| 247 OldCompletionCallback* callback, | 247 const CompletionCallback& callback, |
| 248 const BoundNetLog& net_log) { | 248 const BoundNetLog& net_log) { |
| 249 net_log_ = net_log; | 249 net_log_ = net_log; |
| 250 request_ = request_info; | 250 request_ = request_info; |
| 251 | 251 |
| 252 if (request_->url.has_username()) { | 252 if (request_->url.has_username()) { |
| 253 string16 username; | 253 string16 username; |
| 254 string16 password; | 254 string16 password; |
| 255 GetIdentityFromURL(request_->url, &username, &password); | 255 GetIdentityFromURL(request_->url, &username, &password); |
| 256 credentials_.Set(username, password); | 256 credentials_.Set(username, password); |
| 257 } else { | 257 } else { |
| 258 credentials_.Set(ASCIIToUTF16("anonymous"), | 258 credentials_.Set(ASCIIToUTF16("anonymous"), |
| 259 ASCIIToUTF16("chrome@example.com")); | 259 ASCIIToUTF16("chrome@example.com")); |
| 260 } | 260 } |
| 261 | 261 |
| 262 DetectTypecode(); | 262 DetectTypecode(); |
| 263 | 263 |
| 264 next_state_ = STATE_CTRL_RESOLVE_HOST; | 264 next_state_ = STATE_CTRL_RESOLVE_HOST; |
| 265 int rv = DoLoop(OK); | 265 int rv = DoLoop(OK); |
| 266 if (rv == ERR_IO_PENDING) | 266 if (rv == ERR_IO_PENDING) |
| 267 user_callback_ = callback; | 267 user_callback_ = callback; |
| 268 return rv; | 268 return rv; |
| 269 } | 269 } |
| 270 | 270 |
| 271 int FtpNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials, | 271 int FtpNetworkTransaction::RestartWithAuth(const AuthCredentials& credentials, |
| 272 OldCompletionCallback* callback) { | 272 const CompletionCallback& callback) { |
| 273 ResetStateForRestart(); | 273 ResetStateForRestart(); |
| 274 | 274 |
| 275 credentials_ = credentials; | 275 credentials_ = credentials; |
| 276 | 276 |
| 277 next_state_ = STATE_CTRL_RESOLVE_HOST; | 277 next_state_ = STATE_CTRL_RESOLVE_HOST; |
| 278 int rv = DoLoop(OK); | 278 int rv = DoLoop(OK); |
| 279 if (rv == ERR_IO_PENDING) | 279 if (rv == ERR_IO_PENDING) |
| 280 user_callback_ = callback; | 280 user_callback_ = callback; |
| 281 return rv; | 281 return rv; |
| 282 } | 282 } |
| 283 | 283 |
| 284 int FtpNetworkTransaction::Read(IOBuffer* buf, | 284 int FtpNetworkTransaction::Read(IOBuffer* buf, |
| 285 int buf_len, | 285 int buf_len, |
| 286 OldCompletionCallback* callback) { | 286 const CompletionCallback& callback) { |
| 287 DCHECK(buf); | 287 DCHECK(buf); |
| 288 DCHECK_GT(buf_len, 0); | 288 DCHECK_GT(buf_len, 0); |
| 289 | 289 |
| 290 read_data_buf_ = buf; | 290 read_data_buf_ = buf; |
| 291 read_data_buf_len_ = buf_len; | 291 read_data_buf_len_ = buf_len; |
| 292 | 292 |
| 293 next_state_ = STATE_DATA_READ; | 293 next_state_ = STATE_DATA_READ; |
| 294 int rv = DoLoop(OK); | 294 int rv = DoLoop(OK); |
| 295 if (rv == ERR_IO_PENDING) | 295 if (rv == ERR_IO_PENDING) |
| 296 user_callback_ = callback; | 296 user_callback_ = callback; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 323 | 323 |
| 324 return LOAD_STATE_IDLE; | 324 return LOAD_STATE_IDLE; |
| 325 } | 325 } |
| 326 | 326 |
| 327 uint64 FtpNetworkTransaction::GetUploadProgress() const { | 327 uint64 FtpNetworkTransaction::GetUploadProgress() const { |
| 328 return 0; | 328 return 0; |
| 329 } | 329 } |
| 330 | 330 |
| 331 void FtpNetworkTransaction::ResetStateForRestart() { | 331 void FtpNetworkTransaction::ResetStateForRestart() { |
| 332 command_sent_ = COMMAND_NONE; | 332 command_sent_ = COMMAND_NONE; |
| 333 user_callback_ = NULL; | 333 user_callback_.Reset(); |
| 334 response_ = FtpResponseInfo(); | 334 response_ = FtpResponseInfo(); |
| 335 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); | 335 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); |
| 336 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer()); | 336 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer()); |
| 337 read_data_buf_ = NULL; | 337 read_data_buf_ = NULL; |
| 338 read_data_buf_len_ = 0; | 338 read_data_buf_len_ = 0; |
| 339 if (write_buf_) | 339 if (write_buf_) |
| 340 write_buf_->SetOffset(0); | 340 write_buf_->SetOffset(0); |
| 341 last_error_ = OK; | 341 last_error_ = OK; |
| 342 data_connection_port_ = 0; | 342 data_connection_port_ = 0; |
| 343 ctrl_socket_.reset(); | 343 ctrl_socket_.reset(); |
| 344 data_socket_.reset(); | 344 data_socket_.reset(); |
| 345 next_state_ = STATE_NONE; | 345 next_state_ = STATE_NONE; |
| 346 } | 346 } |
| 347 | 347 |
| 348 void FtpNetworkTransaction::DoCallback(int rv) { | 348 void FtpNetworkTransaction::DoCallback(int rv) { |
| 349 DCHECK(rv != ERR_IO_PENDING); | 349 DCHECK(rv != ERR_IO_PENDING); |
| 350 DCHECK(user_callback_); | 350 DCHECK(!user_callback_.is_null()); |
| 351 | 351 |
| 352 // Since Run may result in Read being called, clear callback_ up front. | 352 // Since Run may result in Read being called, clear callback_ up front. |
| 353 OldCompletionCallback* c = user_callback_; | 353 CompletionCallback c = user_callback_; |
| 354 user_callback_ = NULL; | 354 user_callback_.Reset(); |
| 355 c->Run(rv); | 355 c.Run(rv); |
| 356 } | 356 } |
| 357 | 357 |
| 358 void FtpNetworkTransaction::OnIOComplete(int result) { | 358 void FtpNetworkTransaction::OnIOComplete(int result) { |
| 359 int rv = DoLoop(result); | 359 int rv = DoLoop(result); |
| 360 if (rv != ERR_IO_PENDING) | 360 if (rv != ERR_IO_PENDING) |
| 361 DoCallback(rv); | 361 DoCallback(rv); |
| 362 } | 362 } |
| 363 | 363 |
| 364 int FtpNetworkTransaction::ProcessCtrlResponse() { | 364 int FtpNetworkTransaction::ProcessCtrlResponse() { |
| 365 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse(); | 365 FtpCtrlResponse response = ctrl_response_buffer_->PopResponse(); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { | 638 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { |
| 639 if (result == OK) | 639 if (result == OK) |
| 640 next_state_ = STATE_CTRL_CONNECT; | 640 next_state_ = STATE_CTRL_CONNECT; |
| 641 return result; | 641 return result; |
| 642 } | 642 } |
| 643 | 643 |
| 644 int FtpNetworkTransaction::DoCtrlConnect() { | 644 int FtpNetworkTransaction::DoCtrlConnect() { |
| 645 next_state_ = STATE_CTRL_CONNECT_COMPLETE; | 645 next_state_ = STATE_CTRL_CONNECT_COMPLETE; |
| 646 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( | 646 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( |
| 647 addresses_, net_log_.net_log(), net_log_.source())); | 647 addresses_, net_log_.net_log(), net_log_.source())); |
| 648 return ctrl_socket_->Connect(&io_callback_); | 648 return ctrl_socket_->Connect(io_callback_); |
| 649 } | 649 } |
| 650 | 650 |
| 651 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { | 651 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { |
| 652 if (result == OK) { | 652 if (result == OK) { |
| 653 // Put the peer's IP address and port into the response. | 653 // Put the peer's IP address and port into the response. |
| 654 AddressList address; | 654 AddressList address; |
| 655 result = ctrl_socket_->GetPeerAddress(&address); | 655 result = ctrl_socket_->GetPeerAddress(&address); |
| 656 if (result == OK) { | 656 if (result == OK) { |
| 657 response_.socket_address = HostPortPair::FromAddrInfo(address.head()); | 657 response_.socket_address = HostPortPair::FromAddrInfo(address.head()); |
| 658 next_state_ = STATE_CTRL_READ; | 658 next_state_ = STATE_CTRL_READ; |
| 659 } | 659 } |
| 660 } | 660 } |
| 661 return result; | 661 return result; |
| 662 } | 662 } |
| 663 | 663 |
| 664 int FtpNetworkTransaction::DoCtrlRead() { | 664 int FtpNetworkTransaction::DoCtrlRead() { |
| 665 next_state_ = STATE_CTRL_READ_COMPLETE; | 665 next_state_ = STATE_CTRL_READ_COMPLETE; |
| 666 return ctrl_socket_->Read( | 666 return ctrl_socket_->Read(read_ctrl_buf_, kCtrlBufLen, io_callback_); |
| 667 read_ctrl_buf_, | |
| 668 kCtrlBufLen, | |
| 669 &io_callback_); | |
| 670 } | 667 } |
| 671 | 668 |
| 672 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { | 669 int FtpNetworkTransaction::DoCtrlReadComplete(int result) { |
| 673 if (result == 0) { | 670 if (result == 0) { |
| 674 // Some servers (for example Pure-FTPd) apparently close the control | 671 // Some servers (for example Pure-FTPd) apparently close the control |
| 675 // connection when anonymous login is not permitted. For more details | 672 // connection when anonymous login is not permitted. For more details |
| 676 // see http://crbug.com/25023. | 673 // see http://crbug.com/25023. |
| 677 if (command_sent_ == COMMAND_USER && | 674 if (command_sent_ == COMMAND_USER && |
| 678 credentials_.username() == ASCIIToUTF16("anonymous")) { | 675 credentials_.username() == ASCIIToUTF16("anonymous")) { |
| 679 response_.needs_auth = true; | 676 response_.needs_auth = true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 692 } | 689 } |
| 693 | 690 |
| 694 return ProcessCtrlResponse(); | 691 return ProcessCtrlResponse(); |
| 695 } | 692 } |
| 696 | 693 |
| 697 int FtpNetworkTransaction::DoCtrlWrite() { | 694 int FtpNetworkTransaction::DoCtrlWrite() { |
| 698 next_state_ = STATE_CTRL_WRITE_COMPLETE; | 695 next_state_ = STATE_CTRL_WRITE_COMPLETE; |
| 699 | 696 |
| 700 return ctrl_socket_->Write(write_buf_, | 697 return ctrl_socket_->Write(write_buf_, |
| 701 write_buf_->BytesRemaining(), | 698 write_buf_->BytesRemaining(), |
| 702 &io_callback_); | 699 io_callback_); |
| 703 } | 700 } |
| 704 | 701 |
| 705 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { | 702 int FtpNetworkTransaction::DoCtrlWriteComplete(int result) { |
| 706 if (result < 0) | 703 if (result < 0) |
| 707 return result; | 704 return result; |
| 708 | 705 |
| 709 write_buf_->DidConsume(result); | 706 write_buf_->DidConsume(result); |
| 710 if (write_buf_->BytesRemaining() == 0) { | 707 if (write_buf_->BytesRemaining() == 0) { |
| 711 // Clear the write buffer. | 708 // Clear the write buffer. |
| 712 write_buf_ = NULL; | 709 write_buf_ = NULL; |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 next_state_ = STATE_DATA_CONNECT_COMPLETE; | 1190 next_state_ = STATE_DATA_CONNECT_COMPLETE; |
| 1194 AddressList data_address; | 1191 AddressList data_address; |
| 1195 // Connect to the same host as the control socket to prevent PASV port | 1192 // Connect to the same host as the control socket to prevent PASV port |
| 1196 // scanning attacks. | 1193 // scanning attacks. |
| 1197 int rv = ctrl_socket_->GetPeerAddress(&data_address); | 1194 int rv = ctrl_socket_->GetPeerAddress(&data_address); |
| 1198 if (rv != OK) | 1195 if (rv != OK) |
| 1199 return Stop(rv); | 1196 return Stop(rv); |
| 1200 data_address.SetPort(data_connection_port_); | 1197 data_address.SetPort(data_connection_port_); |
| 1201 data_socket_.reset(socket_factory_->CreateTransportClientSocket( | 1198 data_socket_.reset(socket_factory_->CreateTransportClientSocket( |
| 1202 data_address, net_log_.net_log(), net_log_.source())); | 1199 data_address, net_log_.net_log(), net_log_.source())); |
| 1203 return data_socket_->Connect(&io_callback_); | 1200 return data_socket_->Connect(io_callback_); |
| 1204 } | 1201 } |
| 1205 | 1202 |
| 1206 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1203 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
| 1207 if (result != OK && use_epsv_) { | 1204 if (result != OK && use_epsv_) { |
| 1208 // It's possible we hit a broken server, sadly. They can break in different | 1205 // It's possible we hit a broken server, sadly. They can break in different |
| 1209 // ways. Some time out, some reset a connection. Fall back to PASV. | 1206 // ways. Some time out, some reset a connection. Fall back to PASV. |
| 1210 // TODO(phajdan.jr): remember it for future transactions with this server. | 1207 // TODO(phajdan.jr): remember it for future transactions with this server. |
| 1211 // TODO(phajdan.jr): write a test for this code path. | 1208 // TODO(phajdan.jr): write a test for this code path. |
| 1212 use_epsv_ = false; | 1209 use_epsv_ = false; |
| 1213 next_state_ = STATE_CTRL_WRITE_PASV; | 1210 next_state_ = STATE_CTRL_WRITE_PASV; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1240 next_state_ = STATE_CTRL_READ; | 1237 next_state_ = STATE_CTRL_READ; |
| 1241 return OK; | 1238 return OK; |
| 1242 } | 1239 } |
| 1243 | 1240 |
| 1244 // We are no longer connected to the server, so just finish the transaction. | 1241 // We are no longer connected to the server, so just finish the transaction. |
| 1245 return Stop(OK); | 1242 return Stop(OK); |
| 1246 } | 1243 } |
| 1247 | 1244 |
| 1248 next_state_ = STATE_DATA_READ_COMPLETE; | 1245 next_state_ = STATE_DATA_READ_COMPLETE; |
| 1249 read_data_buf_->data()[0] = 0; | 1246 read_data_buf_->data()[0] = 0; |
| 1250 return data_socket_->Read(read_data_buf_, read_data_buf_len_, | 1247 return data_socket_->Read(read_data_buf_, read_data_buf_len_, io_callback_); |
| 1251 &io_callback_); | |
| 1252 } | 1248 } |
| 1253 | 1249 |
| 1254 int FtpNetworkTransaction::DoDataReadComplete(int result) { | 1250 int FtpNetworkTransaction::DoDataReadComplete(int result) { |
| 1255 return result; | 1251 return result; |
| 1256 } | 1252 } |
| 1257 | 1253 |
| 1258 // We're using a histogram as a group of counters, with one bucket for each | 1254 // We're using a histogram as a group of counters, with one bucket for each |
| 1259 // enumeration value. We're only interested in the values of the counters. | 1255 // enumeration value. We're only interested in the values of the counters. |
| 1260 // Ignore the shape, average, and standard deviation of the histograms because | 1256 // Ignore the shape, average, and standard deviation of the histograms because |
| 1261 // they are meaningless. | 1257 // they are meaningless. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 if (!had_error_type[type]) { | 1333 if (!had_error_type[type]) { |
| 1338 had_error_type[type] = true; | 1334 had_error_type[type] = true; |
| 1339 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1335 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
| 1340 type, NUM_OF_NET_ERROR_TYPES); | 1336 type, NUM_OF_NET_ERROR_TYPES); |
| 1341 } | 1337 } |
| 1342 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1338 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
| 1343 type, NUM_OF_NET_ERROR_TYPES); | 1339 type, NUM_OF_NET_ERROR_TYPES); |
| 1344 } | 1340 } |
| 1345 | 1341 |
| 1346 } // namespace net | 1342 } // namespace net |
| OLD | NEW |