diff options
author | Kristian Monsen <kristianm@google.com> | 2011-05-31 20:30:28 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2011-06-14 20:31:41 -0700 |
commit | 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801 (patch) | |
tree | 382278a54ce7a744d62fa510a9a80688cc12434b /net/ftp | |
parent | c4becdd46e31d261b930e4b5a539cbc1d45c23a6 (diff) | |
download | external_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.cc | 7 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_ls_unittest.cc | 8 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_vms.h | 12 | ||||
-rw-r--r-- | net/ftp/ftp_network_transaction.cc | 234 | ||||
-rw-r--r-- | net/ftp/ftp_network_transaction.h | 64 |
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_; }; |