summaryrefslogtreecommitdiffstats
path: root/net/ftp
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-31 23:30:26 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-31 23:30:26 +0000
commit4ac7e43107e67a7a3b534b5efe9e7791378594f1 (patch)
treefea97662c22d0559b1fb9ef1cc8997a475ce3c26 /net/ftp
parenta287cc480eff74f26d8a3b61e7db432ad42d84dd (diff)
downloadchromium_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.cc20
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;