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(new FtpCtrlResponseBuffer(net_log_)); |
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 |