diff options
author | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-20 09:11:34 +0000 |
---|---|---|
committer | phajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-20 09:11:34 +0000 |
commit | 3bc505f8bf627d85a09829020e0ed3265d060e52 (patch) | |
tree | 4d9a011b21e22ac0c9da23847e0878c634df41f4 | |
parent | fa93c1b017cfd261763aea03abe0b54f1eb2dcf4 (diff) | |
download | chromium_src-3bc505f8bf627d85a09829020e0ed3265d060e52.zip chromium_src-3bc505f8bf627d85a09829020e0ed3265d060e52.tar.gz chromium_src-3bc505f8bf627d85a09829020e0ed3265d060e52.tar.bz2 |
FTP: a successful response to SIZE does not mean the resource is a file.
This fixes navigation to some FTP sites, for example
running the qnx FTP server.
BUG=63605
TEST=see bug, net_unittests
Review URL: http://codereview.chromium.org/5227004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66878 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/ftp/ftp_network_transaction.cc | 11 | ||||
-rw-r--r-- | net/ftp/ftp_network_transaction_unittest.cc | 45 |
2 files changed, 43 insertions, 13 deletions
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc index bc1c2a9..bfda5bd 100644 --- a/net/ftp/ftp_network_transaction.cc +++ b/net/ftp/ftp_network_transaction.cc @@ -978,13 +978,10 @@ int FtpNetworkTransaction::ProcessResponseSIZE( if (size < 0) return Stop(ERR_INVALID_RESPONSE); - // Some FTP servers respond with success to the SIZE command - // for directories, and return 0 size. Make sure we don't set - // the resource type to file if that's the case. - if (size > 0) { - response_.expected_content_size = size; - resource_type_ = RESOURCE_TYPE_FILE; - } + // 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; diff --git a/net/ftp/ftp_network_transaction_unittest.cc b/net/ftp/ftp_network_transaction_unittest.cc index 9c9f62e..1c22c5b 100644 --- a/net/ftp/ftp_network_transaction_unittest.cc +++ b/net/ftp/ftp_network_transaction_unittest.cc @@ -331,6 +331,30 @@ class FtpSocketDataProviderVMSDirectoryListingRootDirectory FtpSocketDataProviderVMSDirectoryListingRootDirectory); }; +class FtpSocketDataProviderFileDownloadWithFileTypecode + : public FtpSocketDataProvider { + public: + FtpSocketDataProviderFileDownloadWithFileTypecode() { + } + + virtual MockWriteResult OnWrite(const std::string& data) { + if (InjectFault()) + return MockWriteResult(true, data.length()); + switch (state()) { + case PRE_SIZE: + return Verify("SIZE /file\r\n", data, PRE_RETR, + "213 18\r\n"); + case PRE_RETR: + return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n"); + default: + return FtpSocketDataProvider::OnWrite(data); + } + } + + private: + DISALLOW_COPY_AND_ASSIGN(FtpSocketDataProviderFileDownloadWithFileTypecode); +}; + class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider { public: FtpSocketDataProviderFileDownload() { @@ -341,8 +365,11 @@ class FtpSocketDataProviderFileDownload : public FtpSocketDataProvider { return MockWriteResult(true, data.length()); switch (state()) { case PRE_SIZE: - return Verify("SIZE /file\r\n", data, PRE_RETR, + return Verify("SIZE /file\r\n", data, PRE_CWD, "213 18\r\n"); + case PRE_CWD: + return Verify("CWD /file\r\n", data, PRE_RETR, + "550 Not a directory\r\n"); case PRE_RETR: return Verify("RETR /file\r\n", data, PRE_QUIT, "200 OK\r\n"); default: @@ -452,8 +479,11 @@ class FtpSocketDataProviderVMSFileDownload : public FtpSocketDataProvider { return Verify("PASV\r\n", data, PRE_SIZE, "227 Entering Passive Mode 127,0,0,1,123,456\r\n"); case PRE_SIZE: - return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_RETR, + return Verify("SIZE ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_CWD, "213 18\r\n"); + case PRE_CWD: + return Verify("CWD ANONYMOUS_ROOT:[file]\r\n", data, PRE_RETR, + "550 Not a directory\r\n"); case PRE_RETR: return Verify("RETR ANONYMOUS_ROOT:[000000]file\r\n", data, PRE_QUIT, "200 OK\r\n"); @@ -476,8 +506,11 @@ class FtpSocketDataProviderEscaping : public FtpSocketDataProviderFileDownload { return MockWriteResult(true, data.length()); switch (state()) { case PRE_SIZE: - return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_RETR, + return Verify("SIZE / !\"#$%y\200\201\r\n", data, PRE_CWD, "213 18\r\n"); + case PRE_CWD: + return Verify("CWD / !\"#$%y\200\201\r\n", data, PRE_RETR, + "550 Not a directory\r\n"); case PRE_RETR: return Verify("RETR / !\"#$%y\200\201\r\n", data, PRE_QUIT, "200 OK\r\n"); @@ -891,7 +924,7 @@ TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithPasvFallback) { } TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) { - FtpSocketDataProviderFileDownload ctrl_socket; + FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; ctrl_socket.set_data_type('A'); ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=a", OK); @@ -900,7 +933,7 @@ TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeA) { } TEST_F(FtpNetworkTransactionTest, DownloadTransactionWithTypecodeI) { - FtpSocketDataProviderFileDownload ctrl_socket; + FtpSocketDataProviderFileDownloadWithFileTypecode ctrl_socket; ExecuteTransaction(&ctrl_socket, "ftp://host/file;type=i", OK); // We pass an artificial value of 18 as a response to the SIZE command. @@ -1191,7 +1224,7 @@ TEST_F(FtpNetworkTransactionTest, DownloadTransactionBigSize) { // Pass a valid, but large file size. The transaction should not fail. FtpSocketDataProviderEvilSize ctrl_socket( "213 3204427776\r\n", - FtpSocketDataProvider::PRE_RETR); + FtpSocketDataProvider::PRE_CWD); ExecuteTransaction(&ctrl_socket, "ftp://host/file", OK); EXPECT_EQ(3204427776LL, transaction_.GetResponseInfo()->expected_content_size); |