| 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" |
| 11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/string_split.h" | 12 #include "base/string_split.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "base/values.h" |
| 15 #include "net/base/address_list.h" | 16 #include "net/base/address_list.h" |
| 16 #include "net/base/connection_type_histograms.h" | 17 #include "net/base/connection_type_histograms.h" |
| 17 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
| 18 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 19 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
| 20 #include "net/base/net_util.h" | 21 #include "net/base/net_util.h" |
| 21 #include "net/ftp/ftp_network_session.h" | 22 #include "net/ftp/ftp_network_session.h" |
| 22 #include "net/ftp/ftp_request_info.h" | 23 #include "net/ftp/ftp_request_info.h" |
| 23 #include "net/ftp/ftp_util.h" | 24 #include "net/ftp/ftp_util.h" |
| 24 #include "net/socket/client_socket_factory.h" | 25 #include "net/socket/client_socket_factory.h" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 FtpNetworkSession* session, | 206 FtpNetworkSession* session, |
| 206 ClientSocketFactory* socket_factory) | 207 ClientSocketFactory* socket_factory) |
| 207 : command_sent_(COMMAND_NONE), | 208 : command_sent_(COMMAND_NONE), |
| 208 ALLOW_THIS_IN_INITIALIZER_LIST( | 209 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, | 210 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
| 210 base::Unretained(this)))), | 211 base::Unretained(this)))), |
| 211 session_(session), | 212 session_(session), |
| 212 request_(NULL), | 213 request_(NULL), |
| 213 resolver_(session->host_resolver()), | 214 resolver_(session->host_resolver()), |
| 214 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), | 215 read_ctrl_buf_(new IOBuffer(kCtrlBufLen)), |
| 215 ctrl_response_buffer_(new FtpCtrlResponseBuffer()), | 216 ctrl_response_buffer_(NULL), |
| 216 read_data_buf_len_(0), | 217 read_data_buf_len_(0), |
| 217 last_error_(OK), | 218 last_error_(OK), |
| 218 system_type_(SYSTEM_TYPE_UNKNOWN), | 219 system_type_(SYSTEM_TYPE_UNKNOWN), |
| 219 // Use image (binary) transfer by default. It should always work, | 220 // Use image (binary) transfer by default. It should always work, |
| 220 // whereas the ascii transfer may damage binary data. | 221 // whereas the ascii transfer may damage binary data. |
| 221 data_type_(DATA_TYPE_IMAGE), | 222 data_type_(DATA_TYPE_IMAGE), |
| 222 resource_type_(RESOURCE_TYPE_UNKNOWN), | 223 resource_type_(RESOURCE_TYPE_UNKNOWN), |
| 223 use_epsv_(true), | 224 use_epsv_(true), |
| 224 data_connection_port_(0), | 225 data_connection_port_(0), |
| 225 socket_factory_(socket_factory), | 226 socket_factory_(socket_factory), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 242 const CompletionCallback& callback) { | 243 const CompletionCallback& callback) { |
| 243 return ERR_NOT_IMPLEMENTED; | 244 return ERR_NOT_IMPLEMENTED; |
| 244 } | 245 } |
| 245 | 246 |
| 246 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, | 247 int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info, |
| 247 const CompletionCallback& callback, | 248 const CompletionCallback& callback, |
| 248 const BoundNetLog& net_log) { | 249 const BoundNetLog& net_log) { |
| 249 net_log_ = net_log; | 250 net_log_ = net_log; |
| 250 request_ = request_info; | 251 request_ = request_info; |
| 251 | 252 |
| 253 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer(net_log_)); |
| 254 |
| 252 if (request_->url.has_username()) { | 255 if (request_->url.has_username()) { |
| 253 string16 username; | 256 string16 username; |
| 254 string16 password; | 257 string16 password; |
| 255 GetIdentityFromURL(request_->url, &username, &password); | 258 GetIdentityFromURL(request_->url, &username, &password); |
| 256 credentials_.Set(username, password); | 259 credentials_.Set(username, password); |
| 257 } else { | 260 } else { |
| 258 credentials_.Set(ASCIIToUTF16("anonymous"), | 261 credentials_.Set(ASCIIToUTF16("anonymous"), |
| 259 ASCIIToUTF16("chrome@example.com")); | 262 ASCIIToUTF16("chrome@example.com")); |
| 260 } | 263 } |
| 261 | 264 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 | 329 |
| 327 uint64 FtpNetworkTransaction::GetUploadProgress() const { | 330 uint64 FtpNetworkTransaction::GetUploadProgress() const { |
| 328 return 0; | 331 return 0; |
| 329 } | 332 } |
| 330 | 333 |
| 331 void FtpNetworkTransaction::ResetStateForRestart() { | 334 void FtpNetworkTransaction::ResetStateForRestart() { |
| 332 command_sent_ = COMMAND_NONE; | 335 command_sent_ = COMMAND_NONE; |
| 333 user_callback_.Reset(); | 336 user_callback_.Reset(); |
| 334 response_ = FtpResponseInfo(); | 337 response_ = FtpResponseInfo(); |
| 335 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); | 338 read_ctrl_buf_ = new IOBuffer(kCtrlBufLen); |
| 336 ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer()); | 339 ctrl_response_buffer_.reset(); |
| 337 read_data_buf_ = NULL; | 340 read_data_buf_ = NULL; |
| 338 read_data_buf_len_ = 0; | 341 read_data_buf_len_ = 0; |
| 339 if (write_buf_) | 342 if (write_buf_) |
| 340 write_buf_->SetOffset(0); | 343 write_buf_->SetOffset(0); |
| 341 last_error_ = OK; | 344 last_error_ = OK; |
| 342 data_connection_port_ = 0; | 345 data_connection_port_ = 0; |
| 343 ctrl_socket_.reset(); | 346 ctrl_socket_.reset(); |
| 344 data_socket_.reset(); | 347 data_socket_.reset(); |
| 345 next_state_ = STATE_NONE; | 348 next_state_ = STATE_NONE; |
| 346 } | 349 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 // Multiple responses for other commands are invalid. | 430 // Multiple responses for other commands are invalid. |
| 428 return Stop(ERR_INVALID_RESPONSE); | 431 return Stop(ERR_INVALID_RESPONSE); |
| 429 } | 432 } |
| 430 } | 433 } |
| 431 | 434 |
| 432 return rv; | 435 return rv; |
| 433 } | 436 } |
| 434 | 437 |
| 435 // Used to prepare and send FTP command. | 438 // Used to prepare and send FTP command. |
| 436 int FtpNetworkTransaction::SendFtpCommand(const std::string& command, | 439 int FtpNetworkTransaction::SendFtpCommand(const std::string& command, |
| 440 const std::string& command_for_log, |
| 437 Command cmd) { | 441 Command cmd) { |
| 438 // If we send a new command when we still have unprocessed responses | 442 // If we send a new command when we still have unprocessed responses |
| 439 // for previous commands, the response receiving code will have no way to know | 443 // for previous commands, the response receiving code will have no way to know |
| 440 // which responses are for which command. | 444 // which responses are for which command. |
| 441 DCHECK(!ctrl_response_buffer_->ResponseAvailable()); | 445 DCHECK(!ctrl_response_buffer_->ResponseAvailable()); |
| 442 | 446 |
| 443 DCHECK(!write_command_buf_); | 447 DCHECK(!write_command_buf_); |
| 444 DCHECK(!write_buf_); | 448 DCHECK(!write_buf_); |
| 445 | 449 |
| 446 if (!IsValidFTPCommandString(command)) { | 450 if (!IsValidFTPCommandString(command)) { |
| 447 // Callers should validate the command themselves and return a more specific | 451 // Callers should validate the command themselves and return a more specific |
| 448 // error code. | 452 // error code. |
| 449 NOTREACHED(); | 453 NOTREACHED(); |
| 450 return Stop(ERR_UNEXPECTED); | 454 return Stop(ERR_UNEXPECTED); |
| 451 } | 455 } |
| 452 | 456 |
| 453 command_sent_ = cmd; | 457 command_sent_ = cmd; |
| 454 | 458 |
| 455 write_command_buf_ = new IOBufferWithSize(command.length() + 2); | 459 write_command_buf_ = new IOBufferWithSize(command.length() + 2); |
| 456 write_buf_ = new DrainableIOBuffer(write_command_buf_, | 460 write_buf_ = new DrainableIOBuffer(write_command_buf_, |
| 457 write_command_buf_->size()); | 461 write_command_buf_->size()); |
| 458 memcpy(write_command_buf_->data(), command.data(), command.length()); | 462 memcpy(write_command_buf_->data(), command.data(), command.length()); |
| 459 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2); | 463 memcpy(write_command_buf_->data() + command.length(), kCRLF, 2); |
| 460 | 464 |
| 465 net_log_.AddEvent(NetLog::TYPE_FTP_COMMAND_SENT, |
| 466 NetLog::StringCallback("command", &command_for_log)); |
| 467 |
| 461 next_state_ = STATE_CTRL_WRITE; | 468 next_state_ = STATE_CTRL_WRITE; |
| 462 return OK; | 469 return OK; |
| 463 } | 470 } |
| 464 | 471 |
| 465 std::string FtpNetworkTransaction::GetRequestPathForFtpCommand( | 472 std::string FtpNetworkTransaction::GetRequestPathForFtpCommand( |
| 466 bool is_directory) const { | 473 bool is_directory) const { |
| 467 std::string path(current_remote_directory_); | 474 std::string path(current_remote_directory_); |
| 468 if (request_->url.has_path()) { | 475 if (request_->url.has_path()) { |
| 469 std::string gurl_path(request_->url.path()); | 476 std::string gurl_path(request_->url.path()); |
| 470 | 477 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { | 645 int FtpNetworkTransaction::DoCtrlResolveHostComplete(int result) { |
| 639 if (result == OK) | 646 if (result == OK) |
| 640 next_state_ = STATE_CTRL_CONNECT; | 647 next_state_ = STATE_CTRL_CONNECT; |
| 641 return result; | 648 return result; |
| 642 } | 649 } |
| 643 | 650 |
| 644 int FtpNetworkTransaction::DoCtrlConnect() { | 651 int FtpNetworkTransaction::DoCtrlConnect() { |
| 645 next_state_ = STATE_CTRL_CONNECT_COMPLETE; | 652 next_state_ = STATE_CTRL_CONNECT_COMPLETE; |
| 646 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( | 653 ctrl_socket_.reset(socket_factory_->CreateTransportClientSocket( |
| 647 addresses_, net_log_.net_log(), net_log_.source())); | 654 addresses_, net_log_.net_log(), net_log_.source())); |
| 655 net_log_.AddEvent( |
| 656 NetLog::TYPE_FTP_CONTROL_CONNECTION, |
| 657 ctrl_socket_->NetLog().source().ToEventParametersCallback()); |
| 648 return ctrl_socket_->Connect(io_callback_); | 658 return ctrl_socket_->Connect(io_callback_); |
| 649 } | 659 } |
| 650 | 660 |
| 651 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { | 661 int FtpNetworkTransaction::DoCtrlConnectComplete(int result) { |
| 652 if (result == OK) { | 662 if (result == OK) { |
| 653 // Put the peer's IP address and port into the response. | 663 // Put the peer's IP address and port into the response. |
| 654 IPEndPoint ip_endpoint; | 664 IPEndPoint ip_endpoint; |
| 655 result = ctrl_socket_->GetPeerAddress(&ip_endpoint); | 665 result = ctrl_socket_->GetPeerAddress(&ip_endpoint); |
| 656 if (result == OK) { | 666 if (result == OK) { |
| 657 response_.socket_address = HostPortPair::FromIPEndPoint(ip_endpoint); | 667 response_.socket_address = HostPortPair::FromIPEndPoint(ip_endpoint); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 // FTP Commands and responses | 729 // FTP Commands and responses |
| 720 | 730 |
| 721 // USER Command. | 731 // USER Command. |
| 722 int FtpNetworkTransaction::DoCtrlWriteUSER() { | 732 int FtpNetworkTransaction::DoCtrlWriteUSER() { |
| 723 std::string command = "USER " + UTF16ToUTF8(credentials_.username()); | 733 std::string command = "USER " + UTF16ToUTF8(credentials_.username()); |
| 724 | 734 |
| 725 if (!IsValidFTPCommandString(command)) | 735 if (!IsValidFTPCommandString(command)) |
| 726 return Stop(ERR_MALFORMED_IDENTITY); | 736 return Stop(ERR_MALFORMED_IDENTITY); |
| 727 | 737 |
| 728 next_state_ = STATE_CTRL_READ; | 738 next_state_ = STATE_CTRL_READ; |
| 729 return SendFtpCommand(command, COMMAND_USER); | 739 return SendFtpCommand(command, "USER ***", COMMAND_USER); |
| 730 } | 740 } |
| 731 | 741 |
| 732 int FtpNetworkTransaction::ProcessResponseUSER( | 742 int FtpNetworkTransaction::ProcessResponseUSER( |
| 733 const FtpCtrlResponse& response) { | 743 const FtpCtrlResponse& response) { |
| 734 switch (GetErrorClass(response.status_code)) { | 744 switch (GetErrorClass(response.status_code)) { |
| 735 case ERROR_CLASS_OK: | 745 case ERROR_CLASS_OK: |
| 736 next_state_ = STATE_CTRL_WRITE_SYST; | 746 next_state_ = STATE_CTRL_WRITE_SYST; |
| 737 break; | 747 break; |
| 738 case ERROR_CLASS_INFO_NEEDED: | 748 case ERROR_CLASS_INFO_NEEDED: |
| 739 next_state_ = STATE_CTRL_WRITE_PASS; | 749 next_state_ = STATE_CTRL_WRITE_PASS; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 750 } | 760 } |
| 751 | 761 |
| 752 // PASS command. | 762 // PASS command. |
| 753 int FtpNetworkTransaction::DoCtrlWritePASS() { | 763 int FtpNetworkTransaction::DoCtrlWritePASS() { |
| 754 std::string command = "PASS " + UTF16ToUTF8(credentials_.password()); | 764 std::string command = "PASS " + UTF16ToUTF8(credentials_.password()); |
| 755 | 765 |
| 756 if (!IsValidFTPCommandString(command)) | 766 if (!IsValidFTPCommandString(command)) |
| 757 return Stop(ERR_MALFORMED_IDENTITY); | 767 return Stop(ERR_MALFORMED_IDENTITY); |
| 758 | 768 |
| 759 next_state_ = STATE_CTRL_READ; | 769 next_state_ = STATE_CTRL_READ; |
| 760 return SendFtpCommand(command, COMMAND_PASS); | 770 return SendFtpCommand(command, "PASS ***", COMMAND_PASS); |
| 761 } | 771 } |
| 762 | 772 |
| 763 int FtpNetworkTransaction::ProcessResponsePASS( | 773 int FtpNetworkTransaction::ProcessResponsePASS( |
| 764 const FtpCtrlResponse& response) { | 774 const FtpCtrlResponse& response) { |
| 765 switch (GetErrorClass(response.status_code)) { | 775 switch (GetErrorClass(response.status_code)) { |
| 766 case ERROR_CLASS_OK: | 776 case ERROR_CLASS_OK: |
| 767 next_state_ = STATE_CTRL_WRITE_SYST; | 777 next_state_ = STATE_CTRL_WRITE_SYST; |
| 768 break; | 778 break; |
| 769 case ERROR_CLASS_INFO_NEEDED: | 779 case ERROR_CLASS_INFO_NEEDED: |
| 770 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 780 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
| 771 case ERROR_CLASS_TRANSIENT_ERROR: | 781 case ERROR_CLASS_TRANSIENT_ERROR: |
| 772 case ERROR_CLASS_PERMANENT_ERROR: | 782 case ERROR_CLASS_PERMANENT_ERROR: |
| 773 response_.needs_auth = true; | 783 response_.needs_auth = true; |
| 774 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 784 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
| 775 default: | 785 default: |
| 776 NOTREACHED(); | 786 NOTREACHED(); |
| 777 return Stop(ERR_UNEXPECTED); | 787 return Stop(ERR_UNEXPECTED); |
| 778 } | 788 } |
| 779 return OK; | 789 return OK; |
| 780 } | 790 } |
| 781 | 791 |
| 782 // SYST command. | 792 // SYST command. |
| 783 int FtpNetworkTransaction::DoCtrlWriteSYST() { | 793 int FtpNetworkTransaction::DoCtrlWriteSYST() { |
| 784 std::string command = "SYST"; | 794 std::string command = "SYST"; |
| 785 next_state_ = STATE_CTRL_READ; | 795 next_state_ = STATE_CTRL_READ; |
| 786 return SendFtpCommand(command, COMMAND_SYST); | 796 return SendFtpCommand(command, command, COMMAND_SYST); |
| 787 } | 797 } |
| 788 | 798 |
| 789 int FtpNetworkTransaction::ProcessResponseSYST( | 799 int FtpNetworkTransaction::ProcessResponseSYST( |
| 790 const FtpCtrlResponse& response) { | 800 const FtpCtrlResponse& response) { |
| 791 switch (GetErrorClass(response.status_code)) { | 801 switch (GetErrorClass(response.status_code)) { |
| 792 case ERROR_CLASS_INITIATED: | 802 case ERROR_CLASS_INITIATED: |
| 793 return Stop(ERR_INVALID_RESPONSE); | 803 return Stop(ERR_INVALID_RESPONSE); |
| 794 case ERROR_CLASS_OK: { | 804 case ERROR_CLASS_OK: { |
| 795 // All important info should be on the first line. | 805 // All important info should be on the first line. |
| 796 std::string line = response.lines[0]; | 806 std::string line = response.lines[0]; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 NOTREACHED(); | 839 NOTREACHED(); |
| 830 return Stop(ERR_UNEXPECTED); | 840 return Stop(ERR_UNEXPECTED); |
| 831 } | 841 } |
| 832 return OK; | 842 return OK; |
| 833 } | 843 } |
| 834 | 844 |
| 835 // PWD command. | 845 // PWD command. |
| 836 int FtpNetworkTransaction::DoCtrlWritePWD() { | 846 int FtpNetworkTransaction::DoCtrlWritePWD() { |
| 837 std::string command = "PWD"; | 847 std::string command = "PWD"; |
| 838 next_state_ = STATE_CTRL_READ; | 848 next_state_ = STATE_CTRL_READ; |
| 839 return SendFtpCommand(command, COMMAND_PWD); | 849 return SendFtpCommand(command, command, COMMAND_PWD); |
| 840 } | 850 } |
| 841 | 851 |
| 842 int FtpNetworkTransaction::ProcessResponsePWD(const FtpCtrlResponse& response) { | 852 int FtpNetworkTransaction::ProcessResponsePWD(const FtpCtrlResponse& response) { |
| 843 switch (GetErrorClass(response.status_code)) { | 853 switch (GetErrorClass(response.status_code)) { |
| 844 case ERROR_CLASS_INITIATED: | 854 case ERROR_CLASS_INITIATED: |
| 845 return Stop(ERR_INVALID_RESPONSE); | 855 return Stop(ERR_INVALID_RESPONSE); |
| 846 case ERROR_CLASS_OK: { | 856 case ERROR_CLASS_OK: { |
| 847 // The info we look for should be on the first line. | 857 // The info we look for should be on the first line. |
| 848 std::string line = response.lines[0]; | 858 std::string line = response.lines[0]; |
| 849 if (line.empty()) | 859 if (line.empty()) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 std::string command = "TYPE "; | 892 std::string command = "TYPE "; |
| 883 if (data_type_ == DATA_TYPE_ASCII) { | 893 if (data_type_ == DATA_TYPE_ASCII) { |
| 884 command += "A"; | 894 command += "A"; |
| 885 } else if (data_type_ == DATA_TYPE_IMAGE) { | 895 } else if (data_type_ == DATA_TYPE_IMAGE) { |
| 886 command += "I"; | 896 command += "I"; |
| 887 } else { | 897 } else { |
| 888 NOTREACHED(); | 898 NOTREACHED(); |
| 889 return Stop(ERR_UNEXPECTED); | 899 return Stop(ERR_UNEXPECTED); |
| 890 } | 900 } |
| 891 next_state_ = STATE_CTRL_READ; | 901 next_state_ = STATE_CTRL_READ; |
| 892 return SendFtpCommand(command, COMMAND_TYPE); | 902 return SendFtpCommand(command, command, COMMAND_TYPE); |
| 893 } | 903 } |
| 894 | 904 |
| 895 int FtpNetworkTransaction::ProcessResponseTYPE( | 905 int FtpNetworkTransaction::ProcessResponseTYPE( |
| 896 const FtpCtrlResponse& response) { | 906 const FtpCtrlResponse& response) { |
| 897 switch (GetErrorClass(response.status_code)) { | 907 switch (GetErrorClass(response.status_code)) { |
| 898 case ERROR_CLASS_INITIATED: | 908 case ERROR_CLASS_INITIATED: |
| 899 return Stop(ERR_INVALID_RESPONSE); | 909 return Stop(ERR_INVALID_RESPONSE); |
| 900 case ERROR_CLASS_OK: | 910 case ERROR_CLASS_OK: |
| 901 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; | 911 next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV; |
| 902 break; | 912 break; |
| 903 case ERROR_CLASS_INFO_NEEDED: | 913 case ERROR_CLASS_INFO_NEEDED: |
| 904 return Stop(ERR_INVALID_RESPONSE); | 914 return Stop(ERR_INVALID_RESPONSE); |
| 905 case ERROR_CLASS_TRANSIENT_ERROR: | 915 case ERROR_CLASS_TRANSIENT_ERROR: |
| 906 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 916 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
| 907 case ERROR_CLASS_PERMANENT_ERROR: | 917 case ERROR_CLASS_PERMANENT_ERROR: |
| 908 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); | 918 return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code)); |
| 909 default: | 919 default: |
| 910 NOTREACHED(); | 920 NOTREACHED(); |
| 911 return Stop(ERR_UNEXPECTED); | 921 return Stop(ERR_UNEXPECTED); |
| 912 } | 922 } |
| 913 return OK; | 923 return OK; |
| 914 } | 924 } |
| 915 | 925 |
| 916 // EPSV command | 926 // EPSV command |
| 917 int FtpNetworkTransaction::DoCtrlWriteEPSV() { | 927 int FtpNetworkTransaction::DoCtrlWriteEPSV() { |
| 918 const std::string command = "EPSV"; | 928 const std::string command = "EPSV"; |
| 919 next_state_ = STATE_CTRL_READ; | 929 next_state_ = STATE_CTRL_READ; |
| 920 return SendFtpCommand(command, COMMAND_EPSV); | 930 return SendFtpCommand(command, command, COMMAND_EPSV); |
| 921 } | 931 } |
| 922 | 932 |
| 923 int FtpNetworkTransaction::ProcessResponseEPSV( | 933 int FtpNetworkTransaction::ProcessResponseEPSV( |
| 924 const FtpCtrlResponse& response) { | 934 const FtpCtrlResponse& response) { |
| 925 switch (GetErrorClass(response.status_code)) { | 935 switch (GetErrorClass(response.status_code)) { |
| 926 case ERROR_CLASS_INITIATED: | 936 case ERROR_CLASS_INITIATED: |
| 927 return Stop(ERR_INVALID_RESPONSE); | 937 return Stop(ERR_INVALID_RESPONSE); |
| 928 case ERROR_CLASS_OK: | 938 case ERROR_CLASS_OK: |
| 929 if (!ExtractPortFromEPSVResponse( response, &data_connection_port_)) | 939 if (!ExtractPortFromEPSVResponse( response, &data_connection_port_)) |
| 930 return Stop(ERR_INVALID_RESPONSE); | 940 return Stop(ERR_INVALID_RESPONSE); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 944 NOTREACHED(); | 954 NOTREACHED(); |
| 945 return Stop(ERR_UNEXPECTED); | 955 return Stop(ERR_UNEXPECTED); |
| 946 } | 956 } |
| 947 return OK; | 957 return OK; |
| 948 } | 958 } |
| 949 | 959 |
| 950 // PASV command | 960 // PASV command |
| 951 int FtpNetworkTransaction::DoCtrlWritePASV() { | 961 int FtpNetworkTransaction::DoCtrlWritePASV() { |
| 952 std::string command = "PASV"; | 962 std::string command = "PASV"; |
| 953 next_state_ = STATE_CTRL_READ; | 963 next_state_ = STATE_CTRL_READ; |
| 954 return SendFtpCommand(command, COMMAND_PASV); | 964 return SendFtpCommand(command, command, COMMAND_PASV); |
| 955 } | 965 } |
| 956 | 966 |
| 957 int FtpNetworkTransaction::ProcessResponsePASV( | 967 int FtpNetworkTransaction::ProcessResponsePASV( |
| 958 const FtpCtrlResponse& response) { | 968 const FtpCtrlResponse& response) { |
| 959 switch (GetErrorClass(response.status_code)) { | 969 switch (GetErrorClass(response.status_code)) { |
| 960 case ERROR_CLASS_INITIATED: | 970 case ERROR_CLASS_INITIATED: |
| 961 return Stop(ERR_INVALID_RESPONSE); | 971 return Stop(ERR_INVALID_RESPONSE); |
| 962 case ERROR_CLASS_OK: | 972 case ERROR_CLASS_OK: |
| 963 if (!ExtractPortFromPASVResponse(response, &data_connection_port_)) | 973 if (!ExtractPortFromPASVResponse(response, &data_connection_port_)) |
| 964 return Stop(ERR_INVALID_RESPONSE); | 974 return Stop(ERR_INVALID_RESPONSE); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 977 NOTREACHED(); | 987 NOTREACHED(); |
| 978 return Stop(ERR_UNEXPECTED); | 988 return Stop(ERR_UNEXPECTED); |
| 979 } | 989 } |
| 980 return OK; | 990 return OK; |
| 981 } | 991 } |
| 982 | 992 |
| 983 // RETR command | 993 // RETR command |
| 984 int FtpNetworkTransaction::DoCtrlWriteRETR() { | 994 int FtpNetworkTransaction::DoCtrlWriteRETR() { |
| 985 std::string command = "RETR " + GetRequestPathForFtpCommand(false); | 995 std::string command = "RETR " + GetRequestPathForFtpCommand(false); |
| 986 next_state_ = STATE_CTRL_READ; | 996 next_state_ = STATE_CTRL_READ; |
| 987 return SendFtpCommand(command, COMMAND_RETR); | 997 return SendFtpCommand(command, command, COMMAND_RETR); |
| 988 } | 998 } |
| 989 | 999 |
| 990 int FtpNetworkTransaction::ProcessResponseRETR( | 1000 int FtpNetworkTransaction::ProcessResponseRETR( |
| 991 const FtpCtrlResponse& response) { | 1001 const FtpCtrlResponse& response) { |
| 992 switch (GetErrorClass(response.status_code)) { | 1002 switch (GetErrorClass(response.status_code)) { |
| 993 case ERROR_CLASS_INITIATED: | 1003 case ERROR_CLASS_INITIATED: |
| 994 // We want the client to start reading the response at this point. | 1004 // We want the client to start reading the response at this point. |
| 995 // It got here either through Start or RestartWithAuth. We want that | 1005 // It got here either through Start or RestartWithAuth. We want that |
| 996 // method to complete. Not setting next state here will make DoLoop exit | 1006 // method to complete. Not setting next state here will make DoLoop exit |
| 997 // and in turn make Start/RestartWithAuth complete. | 1007 // and in turn make Start/RestartWithAuth complete. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1028 // an infinite loop (RETR can later send CWD, and CWD can later send RETR). | 1038 // an infinite loop (RETR can later send CWD, and CWD can later send RETR). |
| 1029 DCHECK_NE(RESOURCE_TYPE_UNKNOWN, resource_type_); | 1039 DCHECK_NE(RESOURCE_TYPE_UNKNOWN, resource_type_); |
| 1030 | 1040 |
| 1031 return OK; | 1041 return OK; |
| 1032 } | 1042 } |
| 1033 | 1043 |
| 1034 // SIZE command | 1044 // SIZE command |
| 1035 int FtpNetworkTransaction::DoCtrlWriteSIZE() { | 1045 int FtpNetworkTransaction::DoCtrlWriteSIZE() { |
| 1036 std::string command = "SIZE " + GetRequestPathForFtpCommand(false); | 1046 std::string command = "SIZE " + GetRequestPathForFtpCommand(false); |
| 1037 next_state_ = STATE_CTRL_READ; | 1047 next_state_ = STATE_CTRL_READ; |
| 1038 return SendFtpCommand(command, COMMAND_SIZE); | 1048 return SendFtpCommand(command, command, COMMAND_SIZE); |
| 1039 } | 1049 } |
| 1040 | 1050 |
| 1041 int FtpNetworkTransaction::ProcessResponseSIZE( | 1051 int FtpNetworkTransaction::ProcessResponseSIZE( |
| 1042 const FtpCtrlResponse& response) { | 1052 const FtpCtrlResponse& response) { |
| 1043 switch (GetErrorClass(response.status_code)) { | 1053 switch (GetErrorClass(response.status_code)) { |
| 1044 case ERROR_CLASS_INITIATED: | 1054 case ERROR_CLASS_INITIATED: |
| 1045 break; | 1055 break; |
| 1046 case ERROR_CLASS_OK: | 1056 case ERROR_CLASS_OK: |
| 1047 if (response.lines.size() != 1) | 1057 if (response.lines.size() != 1) |
| 1048 return Stop(ERR_INVALID_RESPONSE); | 1058 return Stop(ERR_INVALID_RESPONSE); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1078 else | 1088 else |
| 1079 next_state_ = STATE_CTRL_WRITE_CWD; | 1089 next_state_ = STATE_CTRL_WRITE_CWD; |
| 1080 | 1090 |
| 1081 return OK; | 1091 return OK; |
| 1082 } | 1092 } |
| 1083 | 1093 |
| 1084 // CWD command | 1094 // CWD command |
| 1085 int FtpNetworkTransaction::DoCtrlWriteCWD() { | 1095 int FtpNetworkTransaction::DoCtrlWriteCWD() { |
| 1086 std::string command = "CWD " + GetRequestPathForFtpCommand(true); | 1096 std::string command = "CWD " + GetRequestPathForFtpCommand(true); |
| 1087 next_state_ = STATE_CTRL_READ; | 1097 next_state_ = STATE_CTRL_READ; |
| 1088 return SendFtpCommand(command, COMMAND_CWD); | 1098 return SendFtpCommand(command, command, COMMAND_CWD); |
| 1089 } | 1099 } |
| 1090 | 1100 |
| 1091 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { | 1101 int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) { |
| 1092 // We should never issue CWD if we know the target resource is a file. | 1102 // We should never issue CWD if we know the target resource is a file. |
| 1093 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); | 1103 DCHECK_NE(RESOURCE_TYPE_FILE, resource_type_); |
| 1094 | 1104 |
| 1095 switch (GetErrorClass(response.status_code)) { | 1105 switch (GetErrorClass(response.status_code)) { |
| 1096 case ERROR_CLASS_INITIATED: | 1106 case ERROR_CLASS_INITIATED: |
| 1097 return Stop(ERR_INVALID_RESPONSE); | 1107 return Stop(ERR_INVALID_RESPONSE); |
| 1098 case ERROR_CLASS_OK: | 1108 case ERROR_CLASS_OK: |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 resource_type_ = RESOURCE_TYPE_FILE; | 1144 resource_type_ = RESOURCE_TYPE_FILE; |
| 1135 next_state_ = STATE_CTRL_WRITE_RETR; | 1145 next_state_ = STATE_CTRL_WRITE_RETR; |
| 1136 | 1146 |
| 1137 return OK; | 1147 return OK; |
| 1138 } | 1148 } |
| 1139 | 1149 |
| 1140 // LIST command | 1150 // LIST command |
| 1141 int FtpNetworkTransaction::DoCtrlWriteLIST() { | 1151 int FtpNetworkTransaction::DoCtrlWriteLIST() { |
| 1142 std::string command(system_type_ == SYSTEM_TYPE_VMS ? "LIST *.*;0" : "LIST"); | 1152 std::string command(system_type_ == SYSTEM_TYPE_VMS ? "LIST *.*;0" : "LIST"); |
| 1143 next_state_ = STATE_CTRL_READ; | 1153 next_state_ = STATE_CTRL_READ; |
| 1144 return SendFtpCommand(command, COMMAND_LIST); | 1154 return SendFtpCommand(command, command, COMMAND_LIST); |
| 1145 } | 1155 } |
| 1146 | 1156 |
| 1147 int FtpNetworkTransaction::ProcessResponseLIST( | 1157 int FtpNetworkTransaction::ProcessResponseLIST( |
| 1148 const FtpCtrlResponse& response) { | 1158 const FtpCtrlResponse& response) { |
| 1149 switch (GetErrorClass(response.status_code)) { | 1159 switch (GetErrorClass(response.status_code)) { |
| 1150 case ERROR_CLASS_INITIATED: | 1160 case ERROR_CLASS_INITIATED: |
| 1151 // We want the client to start reading the response at this point. | 1161 // We want the client to start reading the response at this point. |
| 1152 // It got here either through Start or RestartWithAuth. We want that | 1162 // It got here either through Start or RestartWithAuth. We want that |
| 1153 // method to complete. Not setting next state here will make DoLoop exit | 1163 // method to complete. Not setting next state here will make DoLoop exit |
| 1154 // and in turn make Start/RestartWithAuth complete. | 1164 // and in turn make Start/RestartWithAuth complete. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1168 NOTREACHED(); | 1178 NOTREACHED(); |
| 1169 return Stop(ERR_UNEXPECTED); | 1179 return Stop(ERR_UNEXPECTED); |
| 1170 } | 1180 } |
| 1171 return OK; | 1181 return OK; |
| 1172 } | 1182 } |
| 1173 | 1183 |
| 1174 // QUIT command | 1184 // QUIT command |
| 1175 int FtpNetworkTransaction::DoCtrlWriteQUIT() { | 1185 int FtpNetworkTransaction::DoCtrlWriteQUIT() { |
| 1176 std::string command = "QUIT"; | 1186 std::string command = "QUIT"; |
| 1177 next_state_ = STATE_CTRL_READ; | 1187 next_state_ = STATE_CTRL_READ; |
| 1178 return SendFtpCommand(command, COMMAND_QUIT); | 1188 return SendFtpCommand(command, command, COMMAND_QUIT); |
| 1179 } | 1189 } |
| 1180 | 1190 |
| 1181 int FtpNetworkTransaction::ProcessResponseQUIT( | 1191 int FtpNetworkTransaction::ProcessResponseQUIT( |
| 1182 const FtpCtrlResponse& response) { | 1192 const FtpCtrlResponse& response) { |
| 1183 ctrl_socket_->Disconnect(); | 1193 ctrl_socket_->Disconnect(); |
| 1184 return last_error_; | 1194 return last_error_; |
| 1185 } | 1195 } |
| 1186 | 1196 |
| 1187 // Data Connection | 1197 // Data Connection |
| 1188 | 1198 |
| 1189 int FtpNetworkTransaction::DoDataConnect() { | 1199 int FtpNetworkTransaction::DoDataConnect() { |
| 1190 next_state_ = STATE_DATA_CONNECT_COMPLETE; | 1200 next_state_ = STATE_DATA_CONNECT_COMPLETE; |
| 1191 IPEndPoint ip_endpoint; | 1201 IPEndPoint ip_endpoint; |
| 1192 AddressList data_address; | 1202 AddressList data_address; |
| 1193 // Connect to the same host as the control socket to prevent PASV port | 1203 // Connect to the same host as the control socket to prevent PASV port |
| 1194 // scanning attacks. | 1204 // scanning attacks. |
| 1195 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); | 1205 int rv = ctrl_socket_->GetPeerAddress(&ip_endpoint); |
| 1196 if (rv != OK) | 1206 if (rv != OK) |
| 1197 return Stop(rv); | 1207 return Stop(rv); |
| 1198 data_address = AddressList::CreateFromIPAddress( | 1208 data_address = AddressList::CreateFromIPAddress( |
| 1199 ip_endpoint.address(), data_connection_port_); | 1209 ip_endpoint.address(), data_connection_port_); |
| 1200 data_socket_.reset(socket_factory_->CreateTransportClientSocket( | 1210 data_socket_.reset(socket_factory_->CreateTransportClientSocket( |
| 1201 data_address, net_log_.net_log(), net_log_.source())); | 1211 data_address, net_log_.net_log(), net_log_.source())); |
| 1212 net_log_.AddEvent( |
| 1213 NetLog::TYPE_FTP_DATA_CONNECTION, |
| 1214 data_socket_->NetLog().source().ToEventParametersCallback()); |
| 1202 return data_socket_->Connect(io_callback_); | 1215 return data_socket_->Connect(io_callback_); |
| 1203 } | 1216 } |
| 1204 | 1217 |
| 1205 int FtpNetworkTransaction::DoDataConnectComplete(int result) { | 1218 int FtpNetworkTransaction::DoDataConnectComplete(int result) { |
| 1206 if (result != OK && use_epsv_) { | 1219 if (result != OK && use_epsv_) { |
| 1207 // It's possible we hit a broken server, sadly. They can break in different | 1220 // It's possible we hit a broken server, sadly. They can break in different |
| 1208 // ways. Some time out, some reset a connection. Fall back to PASV. | 1221 // ways. Some time out, some reset a connection. Fall back to PASV. |
| 1209 // TODO(phajdan.jr): remember it for future transactions with this server. | 1222 // TODO(phajdan.jr): remember it for future transactions with this server. |
| 1210 // TODO(phajdan.jr): write a test for this code path. | 1223 // TODO(phajdan.jr): write a test for this code path. |
| 1211 use_epsv_ = false; | 1224 use_epsv_ = false; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 if (!had_error_type[type]) { | 1348 if (!had_error_type[type]) { |
| 1336 had_error_type[type] = true; | 1349 had_error_type[type] = true; |
| 1337 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1350 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
| 1338 type, NUM_OF_NET_ERROR_TYPES); | 1351 type, NUM_OF_NET_ERROR_TYPES); |
| 1339 } | 1352 } |
| 1340 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1353 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
| 1341 type, NUM_OF_NET_ERROR_TYPES); | 1354 type, NUM_OF_NET_ERROR_TYPES); |
| 1342 } | 1355 } |
| 1343 | 1356 |
| 1344 } // namespace net | 1357 } // namespace net |
| OLD | NEW |