summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-20 22:30:13 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-20 22:30:13 +0000
commit13ef7c08cafb5d39c17a3b3e32f0ecf3a1107e2b (patch)
tree6bab505d34a79ee6be99702c657364052a850b72
parente4cdc665ff69c7ddff0ce5740592e735a108e0b7 (diff)
downloadchromium_src-13ef7c08cafb5d39c17a3b3e32f0ecf3a1107e2b.zip
chromium_src-13ef7c08cafb5d39c17a3b3e32f0ecf3a1107e2b.tar.gz
chromium_src-13ef7c08cafb5d39c17a3b3e32f0ecf3a1107e2b.tar.bz2
Port directory lister to allow the linux and mac test shells to display file directories.
This is a revision of r5725. It doesn't break mac build. Review URL: http://codereview.chromium.org/11507 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5792 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/file_util.h14
-rw-r--r--base/file_util_posix.cc48
-rw-r--r--base/file_util_win.cc9
-rw-r--r--net/base/directory_lister.cc112
-rw-r--r--net/base/directory_lister.h30
-rw-r--r--net/base/directory_lister_unittest.cc35
-rw-r--r--net/base/net_util.cc29
-rw-r--r--net/base/net_util.h11
-rw-r--r--net/base/net_util_unittest.cc19
-rw-r--r--net/net.xcodeproj/project.pbxproj4
-rw-r--r--net/net_lib.scons2
-rw-r--r--net/net_unittests.scons2
-rw-r--r--net/url_request/url_request_file_dir_job.cc42
-rw-r--r--net/url_request/url_request_file_dir_job.h10
-rw-r--r--net/url_request/url_request_file_job.cc4
-rw-r--r--net/url_request/url_request_ftp_job.cc7
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);