| Index: net/ftp/ftp_network_transaction.cc
|
| diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
|
| index 17d5754b6c01fb9f98c3ae30891bf6f43b64703d..2b308c7eed4cddf225b90b270d4554a89bd03f8e 100644
|
| --- a/net/ftp/ftp_network_transaction.cc
|
| +++ b/net/ftp/ftp_network_transaction.cc
|
| @@ -224,7 +224,8 @@ FtpNetworkTransaction::FtpNetworkTransaction(
|
| data_connection_port_(0),
|
| socket_factory_(socket_factory),
|
| next_state_(STATE_NONE),
|
| - state_after_data_connect_complete_(STATE_CTRL_WRITE_SIZE) {}
|
| + state_after_data_connect_complete_(STATE_NONE) {
|
| +}
|
|
|
| FtpNetworkTransaction::~FtpNetworkTransaction() {
|
| }
|
| @@ -345,20 +346,13 @@ void FtpNetworkTransaction::ResetStateForRestart() {
|
| ctrl_socket_.reset();
|
| data_socket_.reset();
|
| next_state_ = STATE_NONE;
|
| - state_after_data_connect_complete_ = STATE_CTRL_WRITE_SIZE;
|
| + state_after_data_connect_complete_ = STATE_NONE;
|
| }
|
|
|
| -void FtpNetworkTransaction::ResetDataConnectionAfterError(State next_state) {
|
| - // The server _might_ have reset the data connection
|
| - // (see RFC 959 3.2. ESTABLISHING DATA CONNECTIONS:
|
| - // "The server MUST close the data connection under the following
|
| - // conditions:
|
| - // ...
|
| - // 5. An irrecoverable error condition occurs.")
|
| - //
|
| - // It is ambiguous what an irrecoverable error condition is,
|
| - // so we take no chances.
|
| - state_after_data_connect_complete_ = next_state;
|
| +void FtpNetworkTransaction::EstablishDataConnection(State state_after_connect) {
|
| + DCHECK(state_after_connect == STATE_CTRL_WRITE_RETR ||
|
| + state_after_connect == STATE_CTRL_WRITE_LIST);
|
| + state_after_data_connect_complete_ = state_after_connect;
|
| next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV;
|
| }
|
|
|
| @@ -944,7 +938,7 @@ int FtpNetworkTransaction::ProcessResponseTYPE(
|
| case ERROR_CLASS_INITIATED:
|
| return Stop(ERR_INVALID_RESPONSE);
|
| case ERROR_CLASS_OK:
|
| - next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV;
|
| + next_state_ = STATE_CTRL_WRITE_SIZE;
|
| break;
|
| case ERROR_CLASS_INFO_NEEDED:
|
| return Stop(ERR_INVALID_RESPONSE);
|
| @@ -1056,19 +1050,7 @@ int FtpNetworkTransaction::ProcessResponseRETR(
|
| case ERROR_CLASS_TRANSIENT_ERROR:
|
| return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
|
| case ERROR_CLASS_PERMANENT_ERROR:
|
| - // Code 550 means "Failed to open file". Other codes are unrelated,
|
| - // like "Not logged in" etc.
|
| - if (response.status_code != 550 || resource_type_ == RESOURCE_TYPE_FILE)
|
| - return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
|
| -
|
| - // It's possible that RETR failed because the path is a directory.
|
| - resource_type_ = RESOURCE_TYPE_DIRECTORY;
|
| -
|
| - // We're going to try CWD next, but first send a PASV one more time,
|
| - // because some FTP servers, including FileZilla, require that.
|
| - // See http://crbug.com/25316.
|
| - next_state_ = use_epsv_ ? STATE_CTRL_WRITE_EPSV : STATE_CTRL_WRITE_PASV;
|
| - break;
|
| + return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
|
| default:
|
| NOTREACHED();
|
| return Stop(ERR_UNEXPECTED);
|
| @@ -1090,15 +1072,8 @@ int FtpNetworkTransaction::DoCtrlWriteSIZE() {
|
|
|
| int FtpNetworkTransaction::ProcessResponseSIZE(
|
| const FtpCtrlResponse& response) {
|
| - State state_after_size;
|
| - if (resource_type_ == RESOURCE_TYPE_FILE)
|
| - state_after_size = STATE_CTRL_WRITE_RETR;
|
| - else
|
| - state_after_size = STATE_CTRL_WRITE_CWD;
|
| -
|
| switch (GetErrorClass(response.status_code)) {
|
| case ERROR_CLASS_INITIATED:
|
| - next_state_ = state_after_size;
|
| break;
|
| case ERROR_CLASS_OK:
|
| if (response.lines.size() != 1)
|
| @@ -1113,14 +1088,10 @@ int FtpNetworkTransaction::ProcessResponseSIZE(
|
| // Some FTP servers (for example, the qnx one) send a SIZE even for
|
| // directories.
|
| response_.expected_content_size = size;
|
| -
|
| - next_state_ = state_after_size;
|
| break;
|
| case ERROR_CLASS_INFO_NEEDED:
|
| - next_state_ = state_after_size;
|
| break;
|
| case ERROR_CLASS_TRANSIENT_ERROR:
|
| - ResetDataConnectionAfterError(state_after_size);
|
| break;
|
| case ERROR_CLASS_PERMANENT_ERROR:
|
| // It's possible that SIZE failed because the path is a directory.
|
| @@ -1128,14 +1099,15 @@ int FtpNetworkTransaction::ProcessResponseSIZE(
|
| response.status_code != 550) {
|
| return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
|
| }
|
| -
|
| - ResetDataConnectionAfterError(state_after_size);
|
| break;
|
| default:
|
| NOTREACHED();
|
| return Stop(ERR_UNEXPECTED);
|
| }
|
| -
|
| + if (resource_type_ == RESOURCE_TYPE_FILE)
|
| + EstablishDataConnection(STATE_CTRL_WRITE_RETR);
|
| + else
|
| + next_state_ = STATE_CTRL_WRITE_CWD;
|
| return OK;
|
| }
|
|
|
| @@ -1154,7 +1126,7 @@ int FtpNetworkTransaction::ProcessResponseCWD(const FtpCtrlResponse& response) {
|
| case ERROR_CLASS_INITIATED:
|
| return Stop(ERR_INVALID_RESPONSE);
|
| case ERROR_CLASS_OK:
|
| - next_state_ = STATE_CTRL_WRITE_LIST;
|
| + EstablishDataConnection(STATE_CTRL_WRITE_LIST);
|
| break;
|
| case ERROR_CLASS_INFO_NEEDED:
|
| return Stop(ERR_INVALID_RESPONSE);
|
| @@ -1191,7 +1163,7 @@ int FtpNetworkTransaction::ProcessResponseCWDNotADirectory() {
|
| // an access error (http://crbug.com/56734). Try RETR just to be sure.
|
| resource_type_ = RESOURCE_TYPE_FILE;
|
|
|
| - ResetDataConnectionAfterError(STATE_CTRL_WRITE_RETR);
|
| + EstablishDataConnection(STATE_CTRL_WRITE_RETR);
|
| return OK;
|
| }
|
|
|
|
|