diff options
-rw-r--r-- | base/file_util.h | 14 | ||||
-rw-r--r-- | base/file_util_posix.cc | 48 | ||||
-rw-r--r-- | base/file_util_win.cc | 9 | ||||
-rw-r--r-- | net/base/directory_lister.cc | 112 | ||||
-rw-r--r-- | net/base/directory_lister.h | 30 | ||||
-rw-r--r-- | net/base/directory_lister_unittest.cc | 35 | ||||
-rw-r--r-- | net/base/net_util.cc | 29 | ||||
-rw-r--r-- | net/base/net_util.h | 11 | ||||
-rw-r--r-- | net/base/net_util_unittest.cc | 19 | ||||
-rw-r--r-- | net/net.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | net/net_lib.scons | 2 | ||||
-rw-r--r-- | net/net_unittests.scons | 2 | ||||
-rw-r--r-- | net/url_request/url_request_file_dir_job.cc | 42 | ||||
-rw-r--r-- | net/url_request/url_request_file_dir_job.h | 10 | ||||
-rw-r--r-- | net/url_request/url_request_file_job.cc | 4 | ||||
-rw-r--r-- | net/url_request/url_request_ftp_job.cc | 7 |
16 files changed, 217 insertions, 161 deletions
diff --git a/base/file_util.h b/base/file_util.h index e274d6a..0103003 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -14,6 +14,7 @@ #include <windows.h> #elif defined(OS_POSIX) #include <fts.h> +#include <sys/stat.h> #endif #include <stdio.h> @@ -323,6 +324,15 @@ bool SetCurrentDirectory(const std::wstring& current_directory); // program where latency does not matter. This class is blocking. class FileEnumerator { public: +#if defined(OS_WIN) + typedef WIN32_FIND_DATA FindInfo; +#elif defined(OS_POSIX) + typedef struct { + struct stat stat; + std::string filename; + } FindInfo; +#endif + enum FILE_TYPE { FILES = 0x1, DIRECTORIES = 0x2, @@ -361,6 +371,9 @@ class FileEnumerator { // Returns an empty string if there are no more results. std::wstring Next(); + // Write the file info into |info|. + void GetFindInfo(FindInfo* info); + private: std::wstring root_path_; bool recursive_; @@ -380,6 +393,7 @@ class FileEnumerator { HANDLE find_handle_; #elif defined(OS_POSIX) FTS* fts_; + FTSENT* fts_ent_; #endif DISALLOW_EVIL_CONSTRUCTORS(FileEnumerator); diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 1afb573..5760a68 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -409,6 +409,16 @@ FileEnumerator::~FileEnumerator() { fts_close(fts_); } +void FileEnumerator::GetFindInfo(FindInfo* info) { + DCHECK(info); + + if (!is_in_find_op_) + return; + + memcpy(&(info->stat), fts_ent_->fts_statp, sizeof(info->stat)); + info->filename.assign(fts_ent_->fts_name); +} + // As it stands, this method calls itself recursively when the next item of // the fts enumeration doesn't match (type, pattern, etc.). In the case of // large directories with many files this can be quite deep. @@ -417,12 +427,12 @@ std::wstring FileEnumerator::Next() { if (!is_in_find_op_) { if (pending_paths_.empty()) return std::wstring(); - + // The last find FindFirstFile operation is done, prepare a new one. root_path_ = pending_paths_.top(); TrimTrailingSeparator(&root_path_); pending_paths_.pop(); - + // Start a new find operation. int ftsflags = FTS_LOGICAL; char top_dir[PATH_MAX]; @@ -433,41 +443,41 @@ std::wstring FileEnumerator::Next() { return Next(); is_in_find_op_ = true; } - - FTSENT* fts_ent = fts_read(fts_); - if (fts_ent == NULL) { + + fts_ent_ = fts_read(fts_); + if (fts_ent_ == NULL) { fts_close(fts_); fts_ = NULL; is_in_find_op_ = false; return Next(); } - + // Level 0 is the top, which is always skipped. - if (fts_ent->fts_level == 0) + if (fts_ent_->fts_level == 0) return Next(); - + // Patterns are only matched on the items in the top-most directory. // (see Windows implementation) - if (fts_ent->fts_level == 1 && pattern_.length() > 0) { - if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent->fts_path, 0) != 0) { - if (fts_ent->fts_info == FTS_D) - fts_set(fts_, fts_ent, FTS_SKIP); + if (fts_ent_->fts_level == 1 && pattern_.length() > 0) { + if (fnmatch(WideToUTF8(pattern_).c_str(), fts_ent_->fts_path, 0) != 0) { + if (fts_ent_->fts_info == FTS_D) + fts_set(fts_, fts_ent_, FTS_SKIP); return Next(); } } - - std::wstring cur_file(UTF8ToWide(fts_ent->fts_path)); - if (fts_ent->fts_info == FTS_D) { + + std::wstring cur_file(UTF8ToWide(fts_ent_->fts_path)); + if (fts_ent_->fts_info == FTS_D) { // If not recursive, then prune children. if (!recursive_) - fts_set(fts_, fts_ent, FTS_SKIP); + fts_set(fts_, fts_ent_, FTS_SKIP); return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); - } else if (fts_ent->fts_info == FTS_F) { + } else if (fts_ent_->fts_info == FTS_F) { return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); } // TODO(erikkay) - verify that the other fts_info types aren't interesting return Next(); } - - + + } // namespace file_util diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 459e3a8..fdfd6dd 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -625,6 +625,15 @@ FileEnumerator::~FileEnumerator() { FindClose(find_handle_); } +void FileEnumerator::GetFindInfo(FindInfo* info) { + DCHECK(info); + + if (!is_in_find_op_) + return; + + memcpy(info, &find_data_, sizeof(*info)); +} + std::wstring FileEnumerator::Next() { if (!is_in_find_op_) { if (pending_paths_.empty()) diff --git a/net/base/directory_lister.cc b/net/base/directory_lister.cc index 0204ce4..a04aec2 100644 --- a/net/base/directory_lister.cc +++ b/net/base/directory_lister.cc @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <process.h> - #include "net/base/directory_lister.h" +#include "base/file_util.h" #include "base/message_loop.h" +#include "base/platform_thread.h" +#include "net/base/net_errors.h" namespace net { @@ -27,65 +28,24 @@ class DirectoryDataEvent : public Task { } scoped_refptr<DirectoryLister> lister; - WIN32_FIND_DATA data[kFilesPerEvent]; - int count; - DWORD error; + file_util::FileEnumerator::FindInfo data[kFilesPerEvent]; + int count, error; }; -/*static*/ -unsigned __stdcall DirectoryLister::ThreadFunc(void* param) { - DirectoryLister* self = reinterpret_cast<DirectoryLister*>(param); - - std::wstring pattern = self->directory(); - if (pattern[pattern.size()-1] != '\\') { - pattern.append(L"\\*"); - } else { - pattern.append(L"*"); - } - - DirectoryDataEvent* e = new DirectoryDataEvent(self); - - HANDLE handle = FindFirstFile(pattern.c_str(), &e->data[e->count]); - if (handle == INVALID_HANDLE_VALUE) { - e->error = GetLastError(); - self->message_loop_->PostTask(FROM_HERE, e); - e = NULL; - } else { - do { - if (++e->count == kFilesPerEvent) { - self->message_loop_->PostTask(FROM_HERE, e); - e = new DirectoryDataEvent(self); - } - } while (!self->was_canceled() && FindNextFile(handle, &e->data[e->count])); - - FindClose(handle); - - if (e->count > 0) { - self->message_loop_->PostTask(FROM_HERE, e); - e = NULL; - } - - // Notify done - e = new DirectoryDataEvent(self); - self->message_loop_->PostTask(FROM_HERE, e); - } - - self->Release(); - return 0; -} - -DirectoryLister::DirectoryLister(const std::wstring& dir, Delegate* delegate) +DirectoryLister::DirectoryLister(const std::wstring& dir, + DirectoryListerDelegate* delegate) : dir_(dir), - message_loop_(NULL), delegate_(delegate), + message_loop_(NULL), thread_(NULL), canceled_(false) { DCHECK(!dir.empty()); } DirectoryLister::~DirectoryLister() { - if (thread_) - CloseHandle(thread_); + if (thread_) { + PlatformThread::Join(thread_); + } } bool DirectoryLister::Start() { @@ -97,12 +57,7 @@ bool DirectoryLister::Start() { AddRef(); // the thread will release us when it is done - unsigned thread_id; - thread_ = reinterpret_cast<HANDLE>( - _beginthreadex(NULL, 0, DirectoryLister::ThreadFunc, this, 0, - &thread_id)); - - if (!thread_) { + if (!PlatformThread::Create(0, this, &thread_)) { Release(); return false; } @@ -114,13 +69,48 @@ void DirectoryLister::Cancel() { canceled_ = true; if (thread_) { - WaitForSingleObject(thread_, INFINITE); - CloseHandle(thread_); + PlatformThread::Join(thread_); thread_ = NULL; } } -void DirectoryLister::OnReceivedData(const WIN32_FIND_DATA* data, int count) { +void DirectoryLister::ThreadMain() { + DirectoryDataEvent* e = new DirectoryDataEvent(this); + + if (!file_util::DirectoryExists(directory())) { + e->error = net::ERR_FILE_NOT_FOUND; + message_loop_->PostTask(FROM_HERE, e); + Release(); + return; + } + + file_util::FileEnumerator file_enum(directory(), false, + file_util::FileEnumerator::FILES_AND_DIRECTORIES); + + std::wstring filename; + while (!was_canceled() && !(filename = file_enum.Next()).empty()) { + file_enum.GetFindInfo(&e->data[e->count]); + + if (++e->count == kFilesPerEvent) { + message_loop_->PostTask(FROM_HERE, e); + e = new DirectoryDataEvent(this); + } + } + + if (e->count > 0) { + message_loop_->PostTask(FROM_HERE, e); + e = NULL; + } + + // Notify done + e = new DirectoryDataEvent(this); + message_loop_->PostTask(FROM_HERE, e); + + Release(); +} + +void DirectoryLister::OnReceivedData( + const file_util::FileEnumerator::FindInfo* data, int count) { // Since the delegate can clear itself during the OnListFile callback, we // need to null check it during each iteration of the loop. Similarly, it is // necessary to check the canceled_ flag to avoid sending data to a delegate @@ -133,7 +123,7 @@ void DirectoryLister::OnDone(int error) { // If canceled, we need to report some kind of error, but don't overwrite the // error condition if it is already set. if (!error && canceled_) - error = ERROR_OPERATION_ABORTED; + error = net::ERR_ABORTED; if (delegate_) delegate_->OnListDone(error); diff --git a/net/base/directory_lister.h b/net/base/directory_lister.h index 5f826ce..06d1b37 100644 --- a/net/base/directory_lister.h +++ b/net/base/directory_lister.h @@ -5,9 +5,10 @@ #ifndef NET_BASE_DIRECTORY_LISTER_H__ #define NET_BASE_DIRECTORY_LISTER_H__ -#include <windows.h> #include <string> +#include "base/file_util.h" +#include "base/platform_thread.h" #include "base/ref_counted.h" class MessageLoop; @@ -21,16 +22,18 @@ namespace net { // structs over to the main application thread. The consumer of this class // is insulated from any of the multi-threading details. // -class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> { +class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister>, + public PlatformThread::Delegate { public: // Implement this class to receive directory entries. - class Delegate { + class DirectoryListerDelegate { public: - virtual void OnListFile(const WIN32_FIND_DATA& data) = 0; + virtual void OnListFile( + const file_util::FileEnumerator::FindInfo& data) = 0; virtual void OnListDone(int error) = 0; }; - DirectoryLister(const std::wstring& dir, Delegate* delegate); + DirectoryLister(const std::wstring& dir, DirectoryListerDelegate* delegate); ~DirectoryLister(); // Call this method to start the directory enumeration thread. @@ -42,8 +45,8 @@ class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> { void Cancel(); // The delegate pointer may be modified at any time. - Delegate* delegate() const { return delegate_; } - void set_delegate(Delegate* d) { delegate_ = d; } + DirectoryListerDelegate* delegate() const { return delegate_; } + void set_delegate(DirectoryListerDelegate* d) { delegate_ = d; } // Returns the directory being enumerated. const std::wstring& directory() const { return dir_; } @@ -51,18 +54,21 @@ class DirectoryLister : public base::RefCountedThreadSafe<DirectoryLister> { // Returns true if the directory enumeration was canceled. bool was_canceled() const { return canceled_; } + // PlatformThread::Delegate implementation + void ThreadMain(); + private: friend class DirectoryDataEvent; + friend class ThreadDelegate; - void OnReceivedData(const WIN32_FIND_DATA* data, int count); + void OnReceivedData(const file_util::FileEnumerator::FindInfo* data, + int count); void OnDone(int error); - static unsigned __stdcall ThreadFunc(void* param); - std::wstring dir_; - Delegate* delegate_; + DirectoryListerDelegate* delegate_; MessageLoop* message_loop_; - HANDLE thread_; + PlatformThreadHandle thread_; bool canceled_; }; diff --git a/net/base/directory_lister_unittest.cc b/net/base/directory_lister_unittest.cc index 03b23ba..8f80466 100644 --- a/net/base/directory_lister_unittest.cc +++ b/net/base/directory_lister_unittest.cc @@ -2,23 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/file_path.h" +#include "base/file_util.h" #include "base/message_loop.h" #include "base/path_service.h" #include "net/base/directory_lister.h" +#include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" namespace { - -class DirectoryListerTest : public testing::Test { -}; - +class DirectoryListerTest : public testing::Test {}; } -class DirectoryListerDelegate : public net::DirectoryLister::Delegate { +class ListerDelegate : public net::DirectoryLister::DirectoryListerDelegate { public: - DirectoryListerDelegate() : error_(-1) { + ListerDelegate() : error_(-1) { } - void OnListFile(const WIN32_FIND_DATA& data) { + void OnListFile(const file_util::FileEnumerator::FindInfo& data) { } void OnListDone(int error) { error_ = error; @@ -30,34 +30,33 @@ class DirectoryListerDelegate : public net::DirectoryLister::Delegate { }; TEST(DirectoryListerTest, BigDirTest) { - std::wstring windows_path; - ASSERT_TRUE(PathService::Get(base::DIR_WINDOWS, &windows_path)); + FilePath path; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path)); - DirectoryListerDelegate delegate; + ListerDelegate delegate; scoped_refptr<net::DirectoryLister> lister = - new net::DirectoryLister(windows_path, &delegate); + new net::DirectoryLister(path.ToWStringHack(), &delegate); lister->Start(); MessageLoop::current()->Run(); - EXPECT_EQ(delegate.error(), ERROR_SUCCESS); + EXPECT_EQ(delegate.error(), net::OK); } TEST(DirectoryListerTest, CancelTest) { - std::wstring windows_path; - ASSERT_TRUE(PathService::Get(base::DIR_WINDOWS, &windows_path)); + FilePath path; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path)); - DirectoryListerDelegate delegate; + ListerDelegate delegate; scoped_refptr<net::DirectoryLister> lister = - new net::DirectoryLister(windows_path, &delegate); + new net::DirectoryLister(path.ToWStringHack(), &delegate); lister->Start(); lister->Cancel(); MessageLoop::current()->Run(); - EXPECT_EQ(delegate.error(), ERROR_OPERATION_ABORTED); + EXPECT_EQ(delegate.error(), net::ERR_ABORTED); EXPECT_EQ(lister->was_canceled(), true); } - diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 1617d85..9636df5 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -23,6 +23,7 @@ #include "net/base/net_util.h" #include "base/basictypes.h" +#include "base/file_path.h" #include "base/file_util.h" #include "base/logging.h" #include "base/path_service.h" @@ -797,15 +798,25 @@ std::string CanonicalizeHost(const std::wstring& host, bool* is_ip_address) { WideToUTF8(host.c_str(), host.length(), &converted_host); return CanonicalizeHost(converted_host, is_ip_address); } - -#ifdef OS_WIN + std::string GetDirectoryListingHeader(const std::string& title) { +#if defined(OS_WIN) static const StringPiece header(NetModule::GetResource(IDR_DIR_HEADER_HTML)); if (header.empty()) { NOTREACHED() << "expected resource not found"; } - std::string result(header.data(), header.size()); +#elif defined(OS_POSIX) + // TODO(estade): Temporary hack. Remove these platform #ifdefs when we + // have implemented resources for non-Windows platforms. + LOG(INFO) << "FIXME: hacked resource loading"; + FilePath path; + PathService::Get(base::DIR_EXE, &path); + path = path.Append("../../net/base/dir_header.html"); + std::string result; + file_util::ReadFileToString(path.ToWStringHack(), &result); +#endif + result.append("<script>start("); string_escape::JavascriptDoubleQuote(title, true, &result); result.append(");</script>\n"); @@ -814,16 +825,16 @@ std::string GetDirectoryListingHeader(const std::string& title) { } std::string GetDirectoryListingEntry(const std::string& name, - DWORD attrib, + bool is_dir, int64 size, - const FILETIME* modified) { + const Time& modified) { std::string result; result.append("<script>addRow("); string_escape::JavascriptDoubleQuote(name, true, &result); result.append(","); string_escape::JavascriptDoubleQuote( EscapePath(name), true, &result); - if (attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (is_dir) { result.append(",1,"); } else { result.append(",0,"); @@ -836,9 +847,8 @@ std::string GetDirectoryListingEntry(const std::string& name, std::wstring modified_str; // |modified| can be NULL in FTP listings. - if (modified) { - Time time(Time::FromFileTime(*modified)); - modified_str = base::TimeFormatShortDateAndTime(time); + if (!modified.is_null()) { + modified_str = base::TimeFormatShortDateAndTime(modified); } string_escape::JavascriptDoubleQuote(modified_str, true, &result); @@ -846,7 +856,6 @@ std::string GetDirectoryListingEntry(const std::string& name, return result; } -#endif std::wstring StripWWW(const std::wstring& text) { const std::wstring www(L"www."); diff --git a/net/base/net_util.h b/net/base/net_util.h index 7adfc57..f8f49b8 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -19,6 +19,10 @@ class GURL; +namespace base { +class Time; +} + namespace net { // Given the full path to a file name, creates a file: URL. The returned URL @@ -95,15 +99,12 @@ void IDNToUnicode(const char* host, std::string CanonicalizeHost(const std::string& host, bool* is_ip_address); std::string CanonicalizeHost(const std::wstring& host, bool* is_ip_address); -#ifdef OS_WIN -// TODO: Port GetDirectoryListingEntry for OSX and linux. // Call these functions to get the html for a directory listing. // They will pass non-7bit-ascii characters unescaped, allowing // the browser to interpret the encoding (utf8, etc). std::string GetDirectoryListingHeader(const std::string& title); -std::string GetDirectoryListingEntry(const std::string& name, DWORD attrib, - int64 size, const FILETIME* modified); -#endif +std::string GetDirectoryListingEntry(const std::string& name, bool is_dir, + int64 size, const base::Time& modified); // If text starts with "www." it is removed, otherwise text is returned // unmodified. diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc index 22fb7d4..d1def1c 100644 --- a/net/base/net_util_unittest.cc +++ b/net/base/net_util_unittest.cc @@ -5,6 +5,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/string_util.h" +#include "base/time.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -704,9 +705,9 @@ namespace { struct GetDirectoryListingEntryCase { const char* name; - DWORD file_attrib; + bool is_dir; int64 filesize; - FILETIME* modified; + base::Time time; const char* expected; }; @@ -714,21 +715,23 @@ struct GetDirectoryListingEntryCase { TEST(NetUtilTest, GetDirectoryListingEntry) { const GetDirectoryListingEntryCase test_cases[] = { {"Foo", - 0, + false, 10000, - NULL, + base::Time(), "<script>addRow(\"Foo\",\"Foo\",0,\"9.8 kB\",\"\");</script>\n"}, {"quo\"tes", - 0, + false, 10000, - NULL, + base::Time(), "<script>addRow(\"quo\\\"tes\",\"quo%22tes\",0,\"9.8 kB\",\"\");</script>\n"}, }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { const std::string results = net::GetDirectoryListingEntry( - test_cases[i].name, test_cases[i].file_attrib, - test_cases[i].filesize, test_cases[i].modified); + test_cases[i].name, + test_cases[i].is_dir, + test_cases[i].filesize, + test_cases[i].time); EXPECT_EQ(test_cases[i].expected, results); } } diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj index 6f283a2..55b413a 100644 --- a/net/net.xcodeproj/project.pbxproj +++ b/net/net.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 042A4AB20ED4F02D0001DBED /* url_request_file_dir_job.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33970E5A198600A747DB /* url_request_file_dir_job.cc */; }; + 042A4AB90ED4F0540001DBED /* directory_lister.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED325C0E5A181C00A747DB /* directory_lister.cc */; }; 042A4D480EC4F4500083281F /* http_auth_cache_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 042A4D470EC4F4500083281F /* http_auth_cache_unittest.cc */; }; 0435A4660E8DD69C00E4DF08 /* http_auth.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0435A4650E8DD69C00E4DF08 /* http_auth.cc */; }; 0435A47A0E8DD6F300E4DF08 /* http_auth_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0435A4790E8DD6F300E4DF08 /* http_auth_handler.cc */; }; @@ -1535,6 +1537,8 @@ 821F20A50E5CD414003C7E38 /* url_request_view_cache_job.cc in Sources */, 82113BBD0E892E5800E3848F /* x509_certificate.cc in Sources */, 827E139D0E81611D00183614 /* x509_certificate_mac.cc in Sources */, + 042A4AB20ED4F02D0001DBED /* url_request_file_dir_job.cc in Sources */, + 042A4AB90ED4F0540001DBED /* directory_lister.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/net/net_lib.scons b/net/net_lib.scons index 818fe14..9f080586 100644 --- a/net/net_lib.scons +++ b/net/net_lib.scons @@ -102,11 +102,9 @@ if env['PLATFORM'] in ('posix', 'darwin'): # Remove files that still need to be ported from the input_files list. # TODO(port): delete files from this list as they get ported. to_be_ported_files = [ - 'base/directory_lister.cc', 'base/ssl_config_service.cc', 'http/http_transaction_winhttp.cc', 'http/winhttp_request_throttle.cc', - 'url_request/url_request_file_dir_job.cc', 'url_request/url_request_ftp_job.cc', ] for remove in to_be_ported_files: diff --git a/net/net_unittests.scons b/net/net_unittests.scons index 9f6dda8..bf908ca 100644 --- a/net/net_unittests.scons +++ b/net/net_unittests.scons @@ -42,6 +42,7 @@ input_files = [ 'base/cookie_monster_unittest.cc', 'base/cookie_policy_unittest.cc', 'base/data_url_unittest.cc', + 'base/directory_lister_unittest.cc', 'base/escape_unittest.cc', 'base/file_stream_unittest.cc', 'base/filter_unittest.cc', @@ -81,7 +82,6 @@ input_files = [ if env['PLATFORM'] == 'win32': input_files.extend([ - 'base/directory_lister_unittest.cc', 'base/sdch_filter_unittest.cc', 'base/ssl_config_service_unittest.cc', 'base/wininet_util_unittest.cc', diff --git a/net/url_request/url_request_file_dir_job.cc b/net/url_request/url_request_file_dir_job.cc index 731d741..3685107 100644 --- a/net/url_request/url_request_file_dir_job.cc +++ b/net/url_request/url_request_file_dir_job.cc @@ -7,16 +7,18 @@ #include "base/file_util.h" #include "base/message_loop.h" #include "base/string_util.h" +#include "base/time.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" -#include "net/base/wininet_util.h" #include "net/url_request/url_request.h" +#if defined(OS_POSIX) +#include <sys/stat.h> +#endif + using std::string; using std::wstring; -using net::WinInetUtil; - URLRequestFileDirJob::URLRequestFileDirJob(URLRequest* request, const wstring& dir_path) : URLRequestJob(request), @@ -97,12 +99,8 @@ bool URLRequestFileDirJob::GetCharset(string* charset) { return true; } -void URLRequestFileDirJob::OnListFile(const WIN32_FIND_DATA& data) { - FILETIME local_time; - FileTimeToLocalFileTime(&data.ftLastWriteTime, &local_time); - int64 size = (static_cast<unsigned __int64>(data.nFileSizeHigh) << 32) | - data.nFileSizeLow; - +void URLRequestFileDirJob::OnListFile( + const file_util::FileEnumerator::FindInfo& data) { // We wait to write out the header until we get the first file, so that we // can catch errors from DirectoryLister and show an error page. if (!wrote_header_) { @@ -110,11 +108,27 @@ void URLRequestFileDirJob::OnListFile(const WIN32_FIND_DATA& data) { wrote_header_ = true; } +#if defined(OS_WIN) + FILETIME local_time; + ::FileTimeToLocalFileTime(&data.ftLastWriteTime, &local_time); + int64 size = (static_cast<unsigned __int64>(data.nFileSizeHigh) << 32) | + data.nFileSizeLow; + data_.append(net::GetDirectoryListingEntry( - WideToUTF8(data.cFileName), data.dwFileAttributes, size, &local_time)); + WideToUTF8(data.cFileName), + (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false, + size, + base::Time::FromFileTime(local_time))); - // TODO(darin): coalesce more? +#elif defined(OS_POSIX) + data_.append(net::GetDirectoryListingEntry( + data.filename.c_str(), + S_ISDIR(data.stat.st_mode), + data.stat.st_size, + base::Time::FromTimeT(data.stat.st_mtime))); +#endif + // TODO(darin): coalesce more? CompleteRead(); } @@ -123,8 +137,7 @@ void URLRequestFileDirJob::OnListDone(int error) { if (error) { read_pending_ = false; - NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, - WinInetUtil::OSErrorToNetError(error))); + NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, error)); } else if (canceled_) { read_pending_ = false; NotifyCanceled(); @@ -176,7 +189,8 @@ void URLRequestFileDirJob::CompleteRead() { NotifyReadComplete(bytes_read); } else { NOTREACHED(); - NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, 0)); // TODO: Better error code. + // TODO: Better error code. + NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, 0)); } } } diff --git a/net/url_request/url_request_file_dir_job.h b/net/url_request/url_request_file_dir_job.h index d8e7d43..afbb56b 100644 --- a/net/url_request/url_request_file_dir_job.h +++ b/net/url_request/url_request_file_dir_job.h @@ -5,11 +5,13 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_FILE_DIR_JOB_H__ #define NET_URL_REQUEST_URL_REQUEST_FILE_DIR_JOB_H__ +#include "base/file_util.h" #include "net/base/directory_lister.h" #include "net/url_request/url_request_job.h" -class URLRequestFileDirJob : public URLRequestJob, - public net::DirectoryLister::Delegate { +class URLRequestFileDirJob + : public URLRequestJob, + public net::DirectoryLister::DirectoryListerDelegate { public: URLRequestFileDirJob(URLRequest* request, const std::wstring& dir_path); virtual ~URLRequestFileDirJob(); @@ -22,8 +24,8 @@ class URLRequestFileDirJob : public URLRequestJob, virtual bool GetMimeType(std::string* mime_type); virtual bool GetCharset(std::string* charset); - // DirectoryLister::Delegate methods: - virtual void OnListFile(const WIN32_FIND_DATA& data); + // DirectoryLister::DirectoryListerDelegate methods: + virtual void OnListFile(const file_util::FileEnumerator::FindInfo& data); virtual void OnListDone(int error); private: diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index 608dc64..5c823d8 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc @@ -28,9 +28,7 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/url_request/url_request.h" -#if defined(OS_WIN) #include "net/url_request/url_request_file_dir_job.h" -#endif #if defined(OS_WIN) class URLRequestFileJob::AsyncResolver : @@ -76,10 +74,8 @@ URLRequestJob* URLRequestFileJob::Factory( std::wstring file_path; if (net::FileURLToFilePath(request->url(), &file_path)) { if (file_path[file_path.size() - 1] == file_util::kPathSeparator) { -#if defined(OS_WIN) // Only directories have trailing slashes. return new URLRequestFileDirJob(request, file_path); -#endif } } diff --git a/net/url_request/url_request_ftp_job.cc b/net/url_request/url_request_ftp_job.cc index 9cd7ca9..7b72118 100644 --- a/net/url_request/url_request_ftp_job.cc +++ b/net/url_request/url_request_ftp_job.cc @@ -9,6 +9,7 @@ #include "base/message_loop.h" #include "base/string_util.h" +#include "base/time.h" #include "net/base/auth.h" #include "net/base/load_flags.h" #include "net/base/net_util.h" @@ -378,8 +379,8 @@ void URLRequestFtpJob::OnFindFile(DWORD last_error) { // We don't know the encoding, and can't assume utf8, so pass the 8bit // directly to the browser for it to decide. string file_entry = net::GetDirectoryListingEntry( - find_data_.cFileName, find_data_.dwFileAttributes, size, - &find_data_.ftLastWriteTime); + find_data_.cFileName, false, size, + base::Time::FromFileTime(find_data_.ftLastWriteTime)); WriteData(&file_entry, true); FindNextFile(); @@ -401,7 +402,7 @@ void URLRequestFtpJob::OnStartDirectoryTraversal() { // If this isn't top level directory (i.e. the path isn't "/",) add a link to // the parent directory. if (request_->url().path().length() > 1) - html.append(net::GetDirectoryListingEntry("..", 0, 0, NULL)); + html.append(net::GetDirectoryListingEntry("..", false, 0, base::Time())); WriteData(&html, true); |