diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-31 23:30:26 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-31 23:30:26 +0000 |
commit | 4ac7e43107e67a7a3b534b5efe9e7791378594f1 (patch) | |
tree | fea97662c22d0559b1fb9ef1cc8997a475ce3c26 /net/ftp | |
parent | a287cc480eff74f26d8a3b61e7db432ad42d84dd (diff) | |
download | chromium_src-4ac7e43107e67a7a3b534b5efe9e7791378594f1.zip chromium_src-4ac7e43107e67a7a3b534b5efe9e7791378594f1.tar.gz chromium_src-4ac7e43107e67a7a3b534b5efe9e7791378594f1.tar.bz2 |
Fix a hang if directory listing size is > 8K, for example,
ftp://ftp.mozilla.org/pub/addons/
The problem is that data was spooling on network stack and
after 8K data TCP Window size becomes small and no more
data is received after 8K. The fix is to change the
ERROR_CLASS_INITIATED case in the ProcessResponseLIST
function to not go back to the STATE_CTRL_READ state.
In URLRequestNewFtpJob::ProcessFtpDir. construct the
std::string from buf->data() and its length so that
buf->data() doesn't need to be null-terminated.
Author: Ibrar Ahmed <ibrar.ahmad@gmail.com>
Original review: http://codereview.chromium.org/146137
R=wtc,phajdan.jr
BUG=http://crbug.com/4965
TEST=ftp://ftp.mozilla.org/pub/addons/
Review URL: http://codereview.chromium.org/159663
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22217 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/ftp')
-rw-r--r-- | net/ftp/ftp_network_transaction.cc | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc index ff80fde..95025e7 100644 --- a/net/ftp/ftp_network_transaction.cc +++ b/net/ftp/ftp_network_transaction.cc @@ -83,24 +83,15 @@ int FtpNetworkTransaction::Read(IOBuffer* buf, int buf_len, CompletionCallback* callback) { DCHECK(buf); - DCHECK(buf_len > 0); - - if (data_socket_ == NULL) - return 0; // Data socket closed, no more data left. - - if (!data_socket_->IsConnected()) - return 0; // Data socket disconnected, no more data left. + DCHECK_GT(buf_len, 0); read_data_buf_ = buf; read_data_buf_len_ = buf_len; next_state_ = STATE_DATA_READ; - int rv = DoLoop(OK); if (rv == ERR_IO_PENDING) user_callback_ = callback; - else if (rv == 0) - data_socket_->Disconnect(); return rv; } @@ -836,7 +827,7 @@ int FtpNetworkTransaction::ProcessResponseLIST( const FtpCtrlResponse& response) { switch (GetErrorClass(response.status_code)) { case ERROR_CLASS_INITIATED: - next_state_ = STATE_CTRL_READ; + response_.is_directory_listing = true; break; case ERROR_CLASS_OK: response_.is_directory_listing = true; @@ -907,7 +898,12 @@ int FtpNetworkTransaction::DoDataConnectComplete(int result) { int FtpNetworkTransaction::DoDataRead() { DCHECK(read_data_buf_); - DCHECK(read_data_buf_len_ > 0); + DCHECK_GT(read_data_buf_len_, 0); + + if (data_socket_ == NULL || !data_socket_->IsConnected()) { + // No more data so send QUIT Command now and wait for response. + return Stop(OK); + } next_state_ = STATE_DATA_READ_COMPLETE; read_data_buf_->data()[0] = 0; |