summaryrefslogtreecommitdiffstats
path: root/net/ftp
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-05-31 20:30:28 +0100
committerKristian Monsen <kristianm@google.com>2011-06-14 20:31:41 -0700
commit72a454cd3513ac24fbdd0e0cb9ad70b86a99b801 (patch)
tree382278a54ce7a744d62fa510a9a80688cc12434b /net/ftp
parentc4becdd46e31d261b930e4b5a539cbc1d45c23a6 (diff)
downloadexternal_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.zip
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.gz
external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.bz2
Merge Chromium.org at r11.0.672.0: Initial merge by git.
Change-Id: I8b4aaf611a2a405fe3fe10e8a94ea7658645c192
Diffstat (limited to 'net/ftp')
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls.cc7
-rw-r--r--net/ftp/ftp_directory_listing_parser_ls_unittest.cc8
-rw-r--r--net/ftp/ftp_directory_listing_parser_vms.h12
-rw-r--r--net/ftp/ftp_network_transaction.cc234
-rw-r--r--net/ftp/ftp_network_transaction.h64
5 files changed, 168 insertions, 157 deletions
diff --git a/net/ftp/ftp_directory_listing_parser_ls.cc b/net/ftp/ftp_directory_listing_parser_ls.cc
index 34ef519..fcb222f 100644
--- a/net/ftp/ftp_directory_listing_parser_ls.cc
+++ b/net/ftp/ftp_directory_listing_parser_ls.cc
@@ -39,10 +39,13 @@ bool LooksLikeUnixPermissionsListing(const string16& text) {
text[0] != '-')
return false;
+ // Do not check the rest of the string. Some servers fail to properly
+ // separate this column from the next column (number of links), resulting
+ // in additional characters at the end. Also, sometimes there is a "+"
+ // sign at the end indicating the file has ACLs set.
return (LooksLikeUnixPermission(text.substr(1, 3)) &&
LooksLikeUnixPermission(text.substr(4, 3)) &&
- LooksLikeUnixPermission(text.substr(7, 3)) &&
- (text.substr(10).empty() || text.substr(10) == ASCIIToUTF16("+")));
+ LooksLikeUnixPermission(text.substr(7, 3)));
}
bool LooksLikePermissionDeniedError(const string16& text) {
diff --git a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
index ea4f094..88bbecd 100644
--- a/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
+++ b/net/ftp/ftp_directory_listing_parser_ls_unittest.cc
@@ -81,6 +81,12 @@ TEST_F(FtpDirectoryListingParserLsTest, Good) {
{ "-rw-r--r-- 1 ftpadmin ftpadmin125435904 Apr 9 2008 .pureftpd-upload",
net::FtpDirectoryListingEntry::FILE, ".pureftpd-upload", 0,
2008, 4, 9, 0, 0 },
+
+ // Tests for "ls -l" style listing with number of links
+ // not separated from permission listing (http://crbug.com/70394).
+ { "drwxr-xr-x1732 266 111 90112 Jun 21 2001 .rda_2",
+ net::FtpDirectoryListingEntry::DIRECTORY, ".rda_2", -1,
+ 2001, 6, 21, 0, 0 },
};
for (size_t i = 0; i < arraysize(good_cases); i++) {
SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
@@ -134,8 +140,6 @@ TEST_F(FtpDirectoryListingParserLsTest, Bad) {
"-rw-r--r-- 1 ftp ftp 528 Foo 01 2007 README",
"drwxrwxrwx 1 owner group 0 Sep 13 0:3 audio",
- "d-wx-wx-wt++ 4 ftp 989 512 Dec 8 15:54 incoming",
- "d-wx-wx-wt$ 4 ftp 989 512 Dec 8 15:54 incoming",
"-qqqqqqqqq+ 2 sys 512 Mar 27 2009 pub",
};
for (size_t i = 0; i < arraysize(bad_cases); i++) {
diff --git a/net/ftp/ftp_directory_listing_parser_vms.h b/net/ftp/ftp_directory_listing_parser_vms.h
index 118365d..6f7fb73 100644
--- a/net/ftp/ftp_directory_listing_parser_vms.h
+++ b/net/ftp/ftp_directory_listing_parser_vms.h
@@ -26,10 +26,6 @@ class FtpDirectoryListingParserVms : public FtpDirectoryListingParser {
virtual FtpDirectoryListingEntry PopEntry();
private:
- // Consumes listing line which is expected to be a directory listing entry
- // (and not a comment etc). Returns true on success.
- bool ConsumeEntryLine(const string16& line);
-
enum State {
STATE_INITIAL,
@@ -46,7 +42,13 @@ class FtpDirectoryListingParserVms : public FtpDirectoryListingParser {
// Indicates that we have successfully received all parts of the listing.
STATE_END,
- } state_;
+ };
+
+ // Consumes listing line which is expected to be a directory listing entry
+ // (and not a comment etc). Returns true on success.
+ bool ConsumeEntryLine(const string16& line);
+
+ State state_;
// VMS can use two physical lines if the filename is long. The first line will
// contain the filename, and the second line everything else. Store the
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index 0285e08..d012818 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -204,6 +204,20 @@ FtpNetworkTransaction::FtpNetworkTransaction(
FtpNetworkTransaction::~FtpNetworkTransaction() {
}
+int FtpNetworkTransaction::Stop(int error) {
+ if (command_sent_ == COMMAND_QUIT)
+ return error;
+
+ next_state_ = STATE_CTRL_WRITE_QUIT;
+ last_error_ = error;
+ return OK;
+}
+
+int FtpNetworkTransaction::RestartIgnoringLastError(
+ CompletionCallback* callback) {
+ return ERR_NOT_IMPLEMENTED;
+}
+
int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
CompletionCallback* callback,
const BoundNetLog& net_log) {
@@ -226,15 +240,6 @@ int FtpNetworkTransaction::Start(const FtpRequestInfo* request_info,
return rv;
}
-int FtpNetworkTransaction::Stop(int error) {
- if (command_sent_ == COMMAND_QUIT)
- return error;
-
- next_state_ = STATE_CTRL_WRITE_QUIT;
- last_error_ = error;
- return OK;
-}
-
int FtpNetworkTransaction::RestartWithAuth(const string16& username,
const string16& password,
CompletionCallback* callback) {
@@ -250,11 +255,6 @@ int FtpNetworkTransaction::RestartWithAuth(const string16& username,
return rv;
}
-int FtpNetworkTransaction::RestartIgnoringLastError(
- CompletionCallback* callback) {
- return ERR_NOT_IMPLEMENTED;
-}
-
int FtpNetworkTransaction::Read(IOBuffer* buf,
int buf_len,
CompletionCallback* callback) {
@@ -302,34 +302,37 @@ uint64 FtpNetworkTransaction::GetUploadProgress() const {
return 0;
}
-// Used to prepare and send FTP command.
-int FtpNetworkTransaction::SendFtpCommand(const std::string& command,
- Command cmd) {
- // If we send a new command when we still have unprocessed responses
- // for previous commands, the response receiving code will have no way to know
- // which responses are for which command.
- DCHECK(!ctrl_response_buffer_->ResponseAvailable());
-
- DCHECK(!write_command_buf_);
- DCHECK(!write_buf_);
-
- if (!IsValidFTPCommandString(command)) {
- // Callers should validate the command themselves and return a more specific
- // error code.
- NOTREACHED();
- return Stop(ERR_UNEXPECTED);
- }
+void FtpNetworkTransaction::ResetStateForRestart() {
+ command_sent_ = COMMAND_NONE;
+ user_callback_ = NULL;
+ response_ = FtpResponseInfo();
+ read_ctrl_buf_ = new IOBuffer(kCtrlBufLen);
+ ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer());
+ read_data_buf_ = NULL;
+ read_data_buf_len_ = 0;
+ if (write_buf_)
+ write_buf_->SetOffset(0);
+ last_error_ = OK;
+ data_connection_port_ = 0;
+ ctrl_socket_.reset();
+ data_socket_.reset();
+ next_state_ = STATE_NONE;
+}
- command_sent_ = cmd;
+void FtpNetworkTransaction::DoCallback(int rv) {
+ DCHECK(rv != ERR_IO_PENDING);
+ DCHECK(user_callback_);
- write_command_buf_ = new IOBufferWithSize(command.length() + 2);
- write_buf_ = new DrainableIOBuffer(write_command_buf_,
- write_command_buf_->size());
- memcpy(write_command_buf_->data(), command.data(), command.length());
- memcpy(write_command_buf_->data() + command.length(), kCRLF, 2);
+ // Since Run may result in Read being called, clear callback_ up front.
+ CompletionCallback* c = user_callback_;
+ user_callback_ = NULL;
+ c->Run(rv);
+}
- next_state_ = STATE_CTRL_WRITE;
- return OK;
+void FtpNetworkTransaction::OnIOComplete(int result) {
+ int rv = DoLoop(result);
+ if (rv != ERR_IO_PENDING)
+ DoCallback(rv);
}
int FtpNetworkTransaction::ProcessCtrlResponse() {
@@ -403,37 +406,34 @@ int FtpNetworkTransaction::ProcessCtrlResponse() {
return rv;
}
-void FtpNetworkTransaction::ResetStateForRestart() {
- command_sent_ = COMMAND_NONE;
- user_callback_ = NULL;
- response_ = FtpResponseInfo();
- read_ctrl_buf_ = new IOBuffer(kCtrlBufLen);
- ctrl_response_buffer_.reset(new FtpCtrlResponseBuffer());
- read_data_buf_ = NULL;
- read_data_buf_len_ = 0;
- if (write_buf_)
- write_buf_->SetOffset(0);
- last_error_ = OK;
- data_connection_port_ = 0;
- ctrl_socket_.reset();
- data_socket_.reset();
- next_state_ = STATE_NONE;
-}
+// Used to prepare and send FTP command.
+int FtpNetworkTransaction::SendFtpCommand(const std::string& command,
+ Command cmd) {
+ // If we send a new command when we still have unprocessed responses
+ // for previous commands, the response receiving code will have no way to know
+ // which responses are for which command.
+ DCHECK(!ctrl_response_buffer_->ResponseAvailable());
-void FtpNetworkTransaction::DoCallback(int rv) {
- DCHECK(rv != ERR_IO_PENDING);
- DCHECK(user_callback_);
+ DCHECK(!write_command_buf_);
+ DCHECK(!write_buf_);
- // Since Run may result in Read being called, clear callback_ up front.
- CompletionCallback* c = user_callback_;
- user_callback_ = NULL;
- c->Run(rv);
-}
+ if (!IsValidFTPCommandString(command)) {
+ // Callers should validate the command themselves and return a more specific
+ // error code.
+ NOTREACHED();
+ return Stop(ERR_UNEXPECTED);
+ }
-void FtpNetworkTransaction::OnIOComplete(int result) {
- int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING)
- DoCallback(rv);
+ command_sent_ = cmd;
+
+ write_command_buf_ = new IOBufferWithSize(command.length() + 2);
+ write_buf_ = new DrainableIOBuffer(write_command_buf_,
+ write_command_buf_->size());
+ memcpy(write_command_buf_->data(), command.data(), command.length());
+ memcpy(write_command_buf_->data() + command.length(), kCRLF, 2);
+
+ next_state_ = STATE_CTRL_WRITE;
+ return OK;
}
std::string FtpNetworkTransaction::GetRequestPathForFtpCommand(
@@ -947,56 +947,6 @@ int FtpNetworkTransaction::ProcessResponsePASV(
return OK;
}
-// SIZE command
-int FtpNetworkTransaction::DoCtrlWriteSIZE() {
- std::string command = "SIZE " + GetRequestPathForFtpCommand(false);
- next_state_ = STATE_CTRL_READ;
- return SendFtpCommand(command, COMMAND_SIZE);
-}
-
-int FtpNetworkTransaction::ProcessResponseSIZE(
- const FtpCtrlResponse& response) {
- switch (GetErrorClass(response.status_code)) {
- case ERROR_CLASS_INITIATED:
- break;
- case ERROR_CLASS_OK:
- if (response.lines.size() != 1)
- return Stop(ERR_INVALID_RESPONSE);
- int64 size;
- if (!base::StringToInt64(response.lines[0], &size))
- return Stop(ERR_INVALID_RESPONSE);
- if (size < 0)
- return Stop(ERR_INVALID_RESPONSE);
-
- // A successful response to SIZE does not mean the resource is a file.
- // Some FTP servers (for example, the qnx one) send a SIZE even for
- // directories.
- response_.expected_content_size = size;
- break;
- case ERROR_CLASS_INFO_NEEDED:
- break;
- case ERROR_CLASS_TRANSIENT_ERROR:
- break;
- case ERROR_CLASS_PERMANENT_ERROR:
- // It's possible that SIZE failed because the path is a directory.
- if (resource_type_ == RESOURCE_TYPE_UNKNOWN &&
- response.status_code != 550) {
- return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
- }
- break;
- default:
- NOTREACHED();
- return Stop(ERR_UNEXPECTED);
- }
-
- if (resource_type_ == RESOURCE_TYPE_FILE)
- next_state_ = STATE_CTRL_WRITE_RETR;
- else
- next_state_ = STATE_CTRL_WRITE_CWD;
-
- return OK;
-}
-
// RETR command
int FtpNetworkTransaction::DoCtrlWriteRETR() {
std::string command = "RETR " + GetRequestPathForFtpCommand(false);
@@ -1048,6 +998,56 @@ int FtpNetworkTransaction::ProcessResponseRETR(
return OK;
}
+// SIZE command
+int FtpNetworkTransaction::DoCtrlWriteSIZE() {
+ std::string command = "SIZE " + GetRequestPathForFtpCommand(false);
+ next_state_ = STATE_CTRL_READ;
+ return SendFtpCommand(command, COMMAND_SIZE);
+}
+
+int FtpNetworkTransaction::ProcessResponseSIZE(
+ const FtpCtrlResponse& response) {
+ switch (GetErrorClass(response.status_code)) {
+ case ERROR_CLASS_INITIATED:
+ break;
+ case ERROR_CLASS_OK:
+ if (response.lines.size() != 1)
+ return Stop(ERR_INVALID_RESPONSE);
+ int64 size;
+ if (!base::StringToInt64(response.lines[0], &size))
+ return Stop(ERR_INVALID_RESPONSE);
+ if (size < 0)
+ return Stop(ERR_INVALID_RESPONSE);
+
+ // A successful response to SIZE does not mean the resource is a file.
+ // Some FTP servers (for example, the qnx one) send a SIZE even for
+ // directories.
+ response_.expected_content_size = size;
+ break;
+ case ERROR_CLASS_INFO_NEEDED:
+ break;
+ case ERROR_CLASS_TRANSIENT_ERROR:
+ break;
+ case ERROR_CLASS_PERMANENT_ERROR:
+ // It's possible that SIZE failed because the path is a directory.
+ if (resource_type_ == RESOURCE_TYPE_UNKNOWN &&
+ response.status_code != 550) {
+ return Stop(GetNetErrorCodeForFtpResponseCode(response.status_code));
+ }
+ break;
+ default:
+ NOTREACHED();
+ return Stop(ERR_UNEXPECTED);
+ }
+
+ if (resource_type_ == RESOURCE_TYPE_FILE)
+ next_state_ = STATE_CTRL_WRITE_RETR;
+ else
+ next_state_ = STATE_CTRL_WRITE_CWD;
+
+ return OK;
+}
+
// CWD command
int FtpNetworkTransaction::DoCtrlWriteCWD() {
std::string command = "CWD " + GetRequestPathForFtpCommand(true);
diff --git a/net/ftp/ftp_network_transaction.h b/net/ftp/ftp_network_transaction.h
index 678308a..c4516a4 100644
--- a/net/ftp/ftp_network_transaction.h
+++ b/net/ftp/ftp_network_transaction.h
@@ -31,15 +31,16 @@ class FtpNetworkTransaction : public FtpTransaction {
ClientSocketFactory* socket_factory);
virtual ~FtpNetworkTransaction();
+ virtual int Stop(int error);
+ virtual int RestartIgnoringLastError(CompletionCallback* callback);
+
// FtpTransaction methods:
virtual int Start(const FtpRequestInfo* request_info,
CompletionCallback* callback,
const BoundNetLog& net_log);
- virtual int Stop(int error);
virtual int RestartWithAuth(const string16& username,
const string16& password,
CompletionCallback* callback);
- virtual int RestartIgnoringLastError(CompletionCallback* callback);
virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
virtual const FtpResponseInfo* GetResponseInfo() const;
virtual LoadState GetLoadState() const;
@@ -87,6 +88,36 @@ class FtpNetworkTransaction : public FtpTransaction {
RESOURCE_TYPE_DIRECTORY,
};
+ enum State {
+ // Control connection states:
+ STATE_CTRL_RESOLVE_HOST,
+ STATE_CTRL_RESOLVE_HOST_COMPLETE,
+ STATE_CTRL_CONNECT,
+ STATE_CTRL_CONNECT_COMPLETE,
+ STATE_CTRL_READ,
+ STATE_CTRL_READ_COMPLETE,
+ STATE_CTRL_WRITE,
+ STATE_CTRL_WRITE_COMPLETE,
+ STATE_CTRL_WRITE_USER,
+ STATE_CTRL_WRITE_PASS,
+ STATE_CTRL_WRITE_SYST,
+ STATE_CTRL_WRITE_TYPE,
+ STATE_CTRL_WRITE_EPSV,
+ STATE_CTRL_WRITE_PASV,
+ STATE_CTRL_WRITE_PWD,
+ STATE_CTRL_WRITE_RETR,
+ STATE_CTRL_WRITE_SIZE,
+ STATE_CTRL_WRITE_CWD,
+ STATE_CTRL_WRITE_LIST,
+ STATE_CTRL_WRITE_QUIT,
+ // Data connection states:
+ STATE_DATA_CONNECT,
+ STATE_DATA_CONNECT_COMPLETE,
+ STATE_DATA_READ,
+ STATE_DATA_READ_COMPLETE,
+ STATE_NONE
+ };
+
// Resets the members of the transaction so it can be restarted.
void ResetStateForRestart();
@@ -211,35 +242,6 @@ class FtpNetworkTransaction : public FtpTransaction {
scoped_ptr<ClientSocket> ctrl_socket_;
scoped_ptr<ClientSocket> data_socket_;
- enum State {
- // Control connection states:
- STATE_CTRL_RESOLVE_HOST,
- STATE_CTRL_RESOLVE_HOST_COMPLETE,
- STATE_CTRL_CONNECT,
- STATE_CTRL_CONNECT_COMPLETE,
- STATE_CTRL_READ,
- STATE_CTRL_READ_COMPLETE,
- STATE_CTRL_WRITE,
- STATE_CTRL_WRITE_COMPLETE,
- STATE_CTRL_WRITE_USER,
- STATE_CTRL_WRITE_PASS,
- STATE_CTRL_WRITE_SYST,
- STATE_CTRL_WRITE_TYPE,
- STATE_CTRL_WRITE_EPSV,
- STATE_CTRL_WRITE_PASV,
- STATE_CTRL_WRITE_PWD,
- STATE_CTRL_WRITE_RETR,
- STATE_CTRL_WRITE_SIZE,
- STATE_CTRL_WRITE_CWD,
- STATE_CTRL_WRITE_LIST,
- STATE_CTRL_WRITE_QUIT,
- // Data connection states:
- STATE_DATA_CONNECT,
- STATE_DATA_CONNECT_COMPLETE,
- STATE_DATA_READ,
- STATE_DATA_READ_COMPLETE,
- STATE_NONE
- };
State next_state_;
};