summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-15 03:20:03 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-15 03:20:03 +0000
commitf698a7f22b36d056bbbfa74aaf910d8ac3b97c23 (patch)
treec21fbd8499daa68203d23e2e25a7ff16e595bd67 /webkit/fileapi
parent95249b6e92c3ac6742139f948028d7f3ec5b9dc6 (diff)
downloadchromium_src-f698a7f22b36d056bbbfa74aaf910d8ac3b97c23.zip
chromium_src-f698a7f22b36d056bbbfa74aaf910d8ac3b97c23.tar.gz
chromium_src-f698a7f22b36d056bbbfa74aaf910d8ac3b97c23.tar.bz2
Hide the FileSystem directory under 'unpredictable' location (part 2)
BUG=58361 TEST=FileSystemPathManager.* Review URL: http://codereview.chromium.org/3724001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62698 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r--webkit/fileapi/file_system_path_manager.cc261
-rw-r--r--webkit/fileapi/file_system_path_manager.h56
-rw-r--r--webkit/fileapi/file_system_path_manager_unittest.cc318
-rw-r--r--webkit/fileapi/file_system_types.h1
4 files changed, 495 insertions, 141 deletions
diff --git a/webkit/fileapi/file_system_path_manager.cc b/webkit/fileapi/file_system_path_manager.cc
index 12c273e..05adafc 100644
--- a/webkit/fileapi/file_system_path_manager.cc
+++ b/webkit/fileapi/file_system_path_manager.cc
@@ -5,9 +5,9 @@
#include "webkit/fileapi/file_system_path_manager.h"
#include "base/file_util.h"
-#include "base/file_util_proxy.h"
#include "base/rand_util.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "base/scoped_callback_factory.h"
#include "base/stringprintf.h"
#include "base/string_util.h"
@@ -24,7 +24,6 @@ using WebKit::WebFileSystem;
using WebKit::WebSecurityOrigin;
using WebKit::WebString;
-using base::FileUtilProxy;
using base::PlatformFileError;
namespace fileapi {
@@ -35,6 +34,12 @@ const FilePath::CharType FileSystemPathManager::kFileSystemDirectory[] =
const char FileSystemPathManager::kPersistentName[] = "Persistent";
const char FileSystemPathManager::kTemporaryName[] = "Temporary";
+static const FilePath::CharType kFileSystemUniqueNamePrefix[] =
+ FILE_PATH_LITERAL("chrome-");
+static const int kFileSystemUniqueLength = 16;
+static const unsigned kFileSystemUniqueDirectoryNameLength =
+ kFileSystemUniqueLength + arraysize(kFileSystemUniqueNamePrefix) - 1;
+
namespace {
// Restricted names.
@@ -59,50 +64,163 @@ inline std::string FilePathStringToASCII(
#endif
}
+FilePath::StringType CreateUniqueDirectoryName(const GURL& origin_url) {
+ // This can be anything but need to be unpredictable.
+ static const FilePath::CharType letters[] = FILE_PATH_LITERAL(
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
+ FilePath::StringType unique(kFileSystemUniqueNamePrefix);
+ for (int i = 0; i < kFileSystemUniqueLength; ++i)
+ unique += letters[base::RandInt(0, arraysize(letters) - 2)];
+ return unique;
+}
+
} // anonymous namespace
+class FileSystemPathManager::GetFileSystemRootPathTask
+ : public base::RefCountedThreadSafe<
+ FileSystemPathManager::GetFileSystemRootPathTask> {
+ public:
+ GetFileSystemRootPathTask(
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const std::string& name,
+ FileSystemPathManager::GetRootPathCallback* callback)
+ : file_message_loop_(file_message_loop),
+ origin_message_loop_proxy_(
+ base::MessageLoopProxy::CreateForCurrentThread()),
+ name_(name),
+ callback_(callback) {
+ }
+
+ void Start(const GURL& origin_url,
+ const FilePath& origin_base_path,
+ bool create) {
+ file_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread,
+ origin_url, origin_base_path, create));
+ }
+
+ private:
+ void GetFileSystemRootPathOnFileThread(
+ const GURL& origin_url,
+ const FilePath& base_path,
+ bool create) {
+ FilePath root;
+ if (ReadOriginDirectory(base_path, origin_url, &root)) {
+ DispatchCallbackOnCallerThread(root);
+ return;
+ }
+
+ if (!create) {
+ DispatchCallbackOnCallerThread(FilePath());
+ return;
+ }
+
+ // Creates the root directory.
+ root = base_path.Append(CreateUniqueDirectoryName(origin_url));
+ if (!file_util::CreateDirectory(root)) {
+ DispatchCallbackOnCallerThread(FilePath());
+ return;
+ }
+ DispatchCallbackOnCallerThread(root);
+ }
+
+ bool ReadOriginDirectory(const FilePath& base_path,
+ const GURL& origin_url,
+ FilePath* unique) {
+ file_util::FileEnumerator file_enum(
+ base_path, false /* recursive */,
+ file_util::FileEnumerator::DIRECTORIES,
+ FilePath::StringType(kFileSystemUniqueNamePrefix) +
+ FILE_PATH_LITERAL("*"));
+ FilePath current;
+ bool found = false;
+ while (!(current = file_enum.Next()).empty()) {
+ if (current.BaseName().value().length() !=
+ kFileSystemUniqueDirectoryNameLength)
+ continue;
+ if (found) {
+ // TODO(kinuko): Should notify the user to ask for some action.
+ LOG(WARNING) << "Unexpectedly found more than one FileSystem "
+ << "directories for " << origin_url;
+ return false;
+ }
+ found = true;
+ *unique = current;
+ }
+ return !unique->empty();
+ }
+
+ void DispatchCallbackOnCallerThread(const FilePath& root_path) {
+ origin_message_loop_proxy_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &GetFileSystemRootPathTask::DispatchCallback,
+ root_path));
+ }
+
+ void DispatchCallback(const FilePath& root_path) {
+ callback_->Run(!root_path.empty(), root_path, name_);
+ }
+
+ scoped_refptr<base::MessageLoopProxy> file_message_loop_;
+ scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
+ std::string name_;
+ scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_;
+};
+
FileSystemPathManager::FileSystemPathManager(
- const FilePath& data_path,
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const FilePath& profile_path,
bool is_incognito,
bool allow_file_access_from_files)
- : base_path_(data_path.Append(kFileSystemDirectory)),
+ : file_message_loop_(file_message_loop),
+ base_path_(profile_path.Append(kFileSystemDirectory)),
is_incognito_(is_incognito),
allow_file_access_from_files_(allow_file_access_from_files) {
}
-bool FileSystemPathManager::GetFileSystemRootPath(
+void FileSystemPathManager::GetFileSystemRootPath(
const GURL& origin_url, fileapi::FileSystemType type,
- FilePath* root_path, std::string* name) const {
- // TODO(kinuko): should return an isolated temporary file system space.
- if (is_incognito_)
- return false;
+ bool create, GetRootPathCallback* callback_ptr) {
+ scoped_ptr<GetRootPathCallback> callback(callback_ptr);
+ if (is_incognito_) {
+ // TODO(kinuko): return an isolated temporary directory.
+ callback->Run(false, FilePath(), std::string());
+ return;
+ }
- if (!IsAllowedScheme(origin_url))
- return false;
+ if (!IsAllowedScheme(origin_url)) {
+ callback->Run(false, FilePath(), std::string());
+ return;
+ }
- std::string storage_identifier = GetStorageIdentifierFromURL(origin_url);
- switch (type) {
- case fileapi::kFileSystemTypeTemporary:
- if (root_path)
- *root_path = base_path_.AppendASCII(storage_identifier)
- .AppendASCII(kTemporaryName);
- if (name)
- *name = storage_identifier + ":" + kTemporaryName;
- return true;
- case fileapi::kFileSystemTypePersistent:
- if (root_path)
- *root_path = base_path_.AppendASCII(storage_identifier)
- .AppendASCII(kPersistentName);
- if (name)
- *name = storage_identifier + ":" + kPersistentName;
- return true;
+ if (type != fileapi::kFileSystemTypeTemporary &&
+ type != fileapi::kFileSystemTypePersistent) {
+ LOG(WARNING) << "Unknown filesystem type is requested:" << type;
+ callback->Run(false, FilePath(), std::string());
+ return;
}
- LOG(WARNING) << "Unknown filesystem type is requested:" << type;
- return false;
+
+ std::string storage_identifier = GetStorageIdentifierFromURL(origin_url);
+
+ std::string type_string;
+ if (type == fileapi::kFileSystemTypeTemporary)
+ type_string = kTemporaryName;
+ else if (type == fileapi::kFileSystemTypePersistent)
+ type_string = kPersistentName;
+ DCHECK(!type_string.empty());
+
+ FilePath origin_base_path = base_path_.AppendASCII(storage_identifier)
+ .AppendASCII(type_string);
+ std::string name = storage_identifier + ":" + type_string;
+
+ scoped_refptr<GetFileSystemRootPathTask> task =
+ new GetFileSystemRootPathTask(file_message_loop_,
+ name, callback.release());
+ task->Start(origin_url, origin_base_path, create);
}
-bool FileSystemPathManager::CheckValidFileSystemPath(
- const FilePath& path) const {
+bool FileSystemPathManager::CrackFileSystemPath(
+ const FilePath& path, GURL* origin_url, FileSystemType* type,
+ FilePath* virtual_path) const {
// Any paths that includes parent references are considered invalid.
if (path.ReferencesParent())
return false;
@@ -112,12 +230,12 @@ bool FileSystemPathManager::CheckValidFileSystemPath(
if (!base_path_.AppendRelativePath(path, &relative))
return false;
- // The relative path from the profile FileSystem path should at least
- // contains two components, one for storage identifier and the other for type
-
+ // The relative path from the profile FileSystem path should contain
+ // at least three components, one for storage identifier, one for type
+ // and one for the 'unique' part.
std::vector<FilePath::StringType> components;
relative.GetComponents(&components);
- if (components.size() < 2)
+ if (components.size() < 3)
return false;
// The second component of the relative path to the root directory
@@ -126,48 +244,42 @@ bool FileSystemPathManager::CheckValidFileSystemPath(
return false;
std::string ascii_type_component = FilePathStringToASCII(components[1]);
- if (ascii_type_component != kPersistentName &&
- ascii_type_component != kTemporaryName)
+ FileSystemType cracked_type = kFileSystemTypeUnknown;
+ if (ascii_type_component == kPersistentName)
+ cracked_type = kFileSystemTypePersistent;
+ else if (ascii_type_component == kTemporaryName)
+ cracked_type = kFileSystemTypeTemporary;
+ else
return false;
- return true;
-}
+ DCHECK(cracked_type != kFileSystemTypeUnknown);
-bool FileSystemPathManager::GetOriginFromPath(
- const FilePath& path, GURL* origin_url) {
- DCHECK(origin_url);
- FilePath relative;
- if (!base_path_.AppendRelativePath(path, &relative)) {
- // The path should be a child of the profile's FileSystem path.
- return false;
- }
- std::vector<FilePath::StringType> components;
- relative.GetComponents(&components);
- if (components.size() < 2) {
- // The relative path should at least contain storage identifier and type.
- return false;
- }
- WebSecurityOrigin web_security_origin =
- WebSecurityOrigin::createFromDatabaseIdentifier(
- webkit_glue::FilePathStringToWebString(components[0]));
- *origin_url = GURL(web_security_origin.toString());
-
- // We need this work-around for file:/// URIs as
- // createFromDatabaseIdentifier returns empty origin_url for them.
- if (allow_file_access_from_files_ && origin_url->spec().empty() &&
- components[0].find(FILE_PATH_LITERAL("file")) == 0) {
- *origin_url = GURL("file:///");
- return true;
+ // The given |path| seems valid. Populates the |origin_url|, |type|
+ // and |virtual_path| if they are given.
+
+ if (origin_url) {
+ WebSecurityOrigin web_security_origin =
+ WebSecurityOrigin::createFromDatabaseIdentifier(
+ webkit_glue::FilePathStringToWebString(components[0]));
+ *origin_url = GURL(web_security_origin.toString());
+
+ // We need this work-around for file:/// URIs as
+ // createFromDatabaseIdentifier returns empty origin_url for them.
+ if (allow_file_access_from_files_ && origin_url->spec().empty() &&
+ components[0].find(FILE_PATH_LITERAL("file")) == 0)
+ *origin_url = GURL("file:///");
}
- return IsAllowedScheme(*origin_url);
-}
+ if (type)
+ *type = cracked_type;
-bool FileSystemPathManager::IsAllowedScheme(const GURL& url) const {
- // Basically we only accept http or https. We allow file:// URLs
- // only if --allow-file-access-from-files flag is given.
- return url.SchemeIs("http") || url.SchemeIs("https") ||
- (url.SchemeIsFile() && allow_file_access_from_files_);
+ if (virtual_path) {
+ virtual_path->clear();
+ for (size_t i = 3; i < components.size(); ++i)
+ *virtual_path = virtual_path->Append(components[i]);
+ }
+
+ return true;
}
bool FileSystemPathManager::IsRestrictedFileName(
@@ -200,6 +312,13 @@ bool FileSystemPathManager::IsRestrictedFileName(
return false;
}
+bool FileSystemPathManager::IsAllowedScheme(const GURL& url) const {
+ // Basically we only accept http or https. We allow file:// URLs
+ // only if --allow-file-access-from-files flag is given.
+ return url.SchemeIs("http") || url.SchemeIs("https") ||
+ (url.SchemeIsFile() && allow_file_access_from_files_);
+}
+
std::string FileSystemPathManager::GetStorageIdentifierFromURL(
const GURL& url) {
WebKit::WebSecurityOrigin web_security_origin =
diff --git a/webkit/fileapi/file_system_path_manager.h b/webkit/fileapi/file_system_path_manager.h
index 505a3c1..f66c02a 100644
--- a/webkit/fileapi/file_system_path_manager.h
+++ b/webkit/fileapi/file_system_path_manager.h
@@ -9,6 +9,7 @@
#include "base/callback.h"
#include "base/file_path.h"
+#include "base/message_loop_proxy.h"
#include "base/scoped_ptr.h"
#include "googleurl/src/gurl.h"
#include "webkit/fileapi/file_system_types.h"
@@ -17,33 +18,47 @@ namespace fileapi {
class FileSystemPathManager {
public:
- FileSystemPathManager(const FilePath& data_path,
+ FileSystemPathManager(scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const FilePath& profile_path,
bool is_incognito,
bool allow_file_access_from_files);
- // Returns the root path and name for the file system specified by given
- // |origin_url| and |type|. Returns true if the file system is available
- // for the profile and |root_path| and |name| are filled successfully.
- bool GetFileSystemRootPath(const GURL& origin_url,
+ // Callback for GetFileSystemRootPath.
+ // If the request is accepted and the root filesystem for the origin exists
+ // the callback is called with success=true and valid root_path and name.
+ // If the request is accepted, |create| is specified for
+ // GetFileSystemRootPath, and the root directory does not exist, it creates
+ // a new one and calls back with success=true if the creation has succeeded.
+ typedef Callback3<bool /* success */,
+ const FilePath& /* root_path */,
+ const std::string& /* name */>::Type GetRootPathCallback;
+
+ // Retrieves the root path for the given |origin_url| and |type|, and
+ // calls the given |callback| with the root path and name.
+ // If |create| is true this also creates the directory if it doesn't exist.
+ void GetFileSystemRootPath(const GURL& origin_url,
fileapi::FileSystemType type,
- FilePath* root_path,
- std::string* name) const;
-
- // Checks if a given |path| is in the FileSystem base directory.
- bool CheckValidFileSystemPath(const FilePath& path) const;
-
- // Retrieves the origin URL for the given |path| and populates
- // |origin_url|. It returns false when the given |path| is not a
- // valid filesystem path.
- bool GetOriginFromPath(const FilePath& path, GURL* origin_url);
+ bool create,
+ GetRootPathCallback* callback);
+
+ // Cracks the given |path|, retrieves the information embedded in the path
+ // and populates |origin_url| and |type|. Also it populates |virtual_path|
+ // that is a sandboxed path in the file system, i.e. the relative path to
+ // the file system's root path for the given origin and type.
+ // It returns false if the path does not conform to the expected
+ // filesystem path format.
+ bool CrackFileSystemPath(const FilePath& path,
+ GURL* origin_url,
+ FileSystemType* type,
+ FilePath* virtual_path) const;
+
+ // Checks if a given |name| contains any restricted names/chars in it.
+ bool IsRestrictedFileName(const FilePath& filename) const;
// Returns true if the given |url|'s scheme is allowed to access
// filesystem.
bool IsAllowedScheme(const GURL& url) const;
- // Checks if a given |filename| contains any restricted names/chars in it.
- bool IsRestrictedFileName(const FilePath& filename) const;
-
// The FileSystem directory name.
static const FilePath::CharType kFileSystemDirectory[];
@@ -52,14 +67,15 @@ class FileSystemPathManager {
private:
class GetFileSystemRootPathTask;
- friend class GetFileSystemRootPathTask;
// Returns the storage identifier string for the given |url|.
static std::string GetStorageIdentifierFromURL(const GURL& url);
+ scoped_refptr<base::MessageLoopProxy> file_message_loop_;
+
const FilePath base_path_;
const bool is_incognito_;
- bool allow_file_access_from_files_;
+ const bool allow_file_access_from_files_;
DISALLOW_COPY_AND_ASSIGN(FileSystemPathManager);
};
diff --git a/webkit/fileapi/file_system_path_manager_unittest.cc b/webkit/fileapi/file_system_path_manager_unittest.cc
index 1e67c3a..1bb39f3 100644
--- a/webkit/fileapi/file_system_path_manager_unittest.cc
+++ b/webkit/fileapi/file_system_path_manager_unittest.cc
@@ -5,13 +5,16 @@
#include "webkit/fileapi/file_system_path_manager.h"
#include "base/basictypes.h"
-#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_callback_factory.h"
#include "base/scoped_ptr.h"
#include "base/scoped_temp_dir.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
-using fileapi::FileSystemPathManager;
+using namespace fileapi;
namespace {
@@ -22,27 +25,44 @@ namespace {
#define PS "/"
#endif
-const FilePath::CharType kTestDataPath[] = FILE_PATH_LITERAL(
- "//tmp/TestingProfilePath");
+struct RootPathTestCase {
+ fileapi::FileSystemType type;
+ const char* origin_url;
+ const char* expected_path;
+};
const struct RootPathTest {
fileapi::FileSystemType type;
- bool off_the_record;
const char* origin_url;
- bool expect_root_path;
const char* expected_path;
} kRootPathTestCases[] = {
- { fileapi::kFileSystemTypeTemporary, false, "http://host:1/",
- true, "FileSystem" PS "http_host_1" PS "Temporary" },
- { fileapi::kFileSystemTypePersistent, false, "http://host:2/",
- true, "FileSystem" PS "http_host_2" PS "Persistent" },
- { fileapi::kFileSystemTypeTemporary, true, "http://host:3/",
- false, "" },
- { fileapi::kFileSystemTypePersistent, true, "http://host:4/",
- false, "" },
- // We disallow file:// URIs to access filesystem.
- { fileapi::kFileSystemTypeTemporary, false, "file:///some/path", false, "" },
- { fileapi::kFileSystemTypePersistent, false, "file:///some/path", false, "" },
+ { fileapi::kFileSystemTypeTemporary, "http://foo:1/",
+ "http_foo_1" PS "Temporary" },
+ { fileapi::kFileSystemTypePersistent, "http://foo:1/",
+ "http_foo_1" PS "Persistent" },
+ { fileapi::kFileSystemTypeTemporary, "http://bar.com/",
+ "http_bar.com_0" PS "Temporary" },
+ { fileapi::kFileSystemTypePersistent, "http://bar.com/",
+ "http_bar.com_0" PS "Persistent" },
+ { fileapi::kFileSystemTypeTemporary, "https://foo:2/",
+ "https_foo_2" PS "Temporary" },
+ { fileapi::kFileSystemTypePersistent, "https://foo:2/",
+ "https_foo_2" PS "Persistent" },
+ { fileapi::kFileSystemTypeTemporary, "https://bar.com/",
+ "https_bar.com_0" PS "Temporary" },
+ { fileapi::kFileSystemTypePersistent, "https://bar.com/",
+ "https_bar.com_0" PS "Persistent" },
+};
+
+const struct RootPathFileURITest {
+ fileapi::FileSystemType type;
+ const char* origin_url;
+ const char* expected_path;
+} kRootPathFileURITestCases[] = {
+ { fileapi::kFileSystemTypeTemporary, "file:///",
+ "file__0" PS "Temporary" },
+ { fileapi::kFileSystemTypePersistent, "file:///",
+ "file__0" PS "Persistent" },
};
const struct CheckValidPathTest {
@@ -59,6 +79,13 @@ const struct CheckValidPathTest {
{ FILE_PATH_LITERAL("a/b/../c/.."), false, },
};
+const char* const kPathToVirtualPathTestCases[] = {
+ "",
+ "a",
+ "a" PS "b",
+ "a" PS "b" PS "c",
+};
+
const struct IsRestrictedNameTest {
FilePath::StringType name;
bool expected_dangerous;
@@ -132,58 +159,249 @@ const struct IsRestrictedNameTest {
class FileSystemPathManagerTest : public testing::Test {
public:
FileSystemPathManagerTest()
- : data_path_(kTestDataPath) {
+ : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ }
+
+ void SetUp() {
+ data_dir_.reset(new ScopedTempDir);
+ data_dir_->CreateUniqueTempDir();
+ ASSERT_TRUE(data_dir_->IsValid());
+ root_path_callback_status_ = false;
+ root_path_.clear();
+ file_system_name_.clear();
+ }
+
+ protected:
+ FileSystemPathManager* NewPathManager(
+ bool incognito,
+ bool allow_file_access) {
+ return new FileSystemPathManager(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ data_dir_->path(), incognito, allow_file_access);
+ }
+
+ void OnGetRootPath(bool success,
+ const FilePath& root_path,
+ const std::string& name) {
+ root_path_callback_status_ = success;
+ root_path_ = root_path;
+ file_system_name_ = name;
}
- FileSystemPathManager* GetNewPathManager(bool incognito) {
- path_manager_.reset(new FileSystemPathManager(
- data_path_, incognito, false /* allow_file_access */));
- return path_manager_.get();
+ bool GetRootPath(FileSystemPathManager* manager,
+ const GURL& origin_url,
+ fileapi::FileSystemType type,
+ bool create,
+ FilePath* root_path) {
+ manager->GetFileSystemRootPath(origin_url, type, create,
+ callback_factory_.NewCallback(
+ &FileSystemPathManagerTest::OnGetRootPath));
+ MessageLoop::current()->RunAllPending();
+ if (root_path)
+ *root_path = root_path_;
+ return root_path_callback_status_;
+ }
+
+ bool CheckValidFileSystemPath(FileSystemPathManager* manager,
+ const FilePath& path) {
+ return manager->CrackFileSystemPath(path, NULL, NULL, NULL);
+ }
+
+ FilePath data_path() { return data_dir_->path(); }
+ FilePath file_system_path() {
+ return data_dir_->path().Append(
+ FileSystemPathManager::kFileSystemDirectory);
}
private:
- FilePath data_path_;
- scoped_ptr<FileSystemPathManager> path_manager_;
+ scoped_ptr<ScopedTempDir> data_dir_;
+ base::ScopedCallbackFactory<FileSystemPathManagerTest> callback_factory_;
+
+ bool root_path_callback_status_;
+ FilePath root_path_;
+ std::string file_system_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileSystemPathManagerTest);
};
-TEST_F(FileSystemPathManagerTest, GetRootPath) {
+TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamine) {
+ std::vector<FilePath> returned_root_path(
+ ARRAYSIZE_UNSAFE(kRootPathTestCases));
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
+
+ // Create a new root directory.
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "RootPath #" << i << " "
+ SCOPED_TRACE(testing::Message() << "RootPath (create) #" << i << " "
<< kRootPathTestCases[i].expected_path);
- FileSystemPathManager* manager = GetNewPathManager(
- kRootPathTestCases[i].off_the_record);
+ FilePath root_path;
+ EXPECT_TRUE(GetRootPath(manager.get(),
+ GURL(kRootPathTestCases[i].origin_url),
+ kRootPathTestCases[i].type,
+ true /* create */, &root_path));
+
+ FilePath expected = file_system_path().AppendASCII(
+ kRootPathTestCases[i].expected_path);
+ EXPECT_EQ(expected.value(), root_path.DirName().value());
+ EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ ASSERT_TRUE(returned_root_path.size() > i);
+ returned_root_path[i] = root_path;
+ }
+
+ // Get the root directory with create=false and see if we get the
+ // same directory.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "RootPath (get) #" << i << " "
+ << kRootPathTestCases[i].expected_path);
FilePath root_path;
- bool result = manager->GetFileSystemRootPath(
- GURL(kRootPathTestCases[i].origin_url),
- kRootPathTestCases[i].type,
- &root_path, NULL);
- EXPECT_EQ(kRootPathTestCases[i].expect_root_path, result);
- if (result) {
- FilePath expected = FilePath(kTestDataPath).AppendASCII(
- kRootPathTestCases[i].expected_path);
- EXPECT_EQ(expected.value(), root_path.value());
- }
+ EXPECT_TRUE(GetRootPath(manager.get(),
+ GURL(kRootPathTestCases[i].origin_url),
+ kRootPathTestCases[i].type,
+ false /* create */, &root_path));
+ ASSERT_TRUE(returned_root_path.size() > i);
+ EXPECT_EQ(returned_root_path[i].value(), root_path.value());
}
}
+TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamineWithNewManager) {
+ std::vector<FilePath> returned_root_path(
+ ARRAYSIZE_UNSAFE(kRootPathTestCases));
+ scoped_ptr<FileSystemPathManager> manager1(NewPathManager(false, false));
+ scoped_ptr<FileSystemPathManager> manager2(NewPathManager(false, false));
+
+ GURL origin_url("http://foo.com:1/");
+
+ FilePath root_path1;
+ EXPECT_TRUE(GetRootPath(manager1.get(), origin_url,
+ kFileSystemTypeTemporary, true, &root_path1));
+ FilePath root_path2;
+ EXPECT_TRUE(GetRootPath(manager2.get(), origin_url,
+ kFileSystemTypeTemporary, false, &root_path2));
+
+ EXPECT_EQ(root_path1.value(), root_path2.value());
+}
+
+TEST_F(FileSystemPathManagerTest, GetRootPathGetWithoutCreate) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
+
+ // Try to get a root directory without creating.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "RootPath (create=false) #" << i << " "
+ << kRootPathTestCases[i].expected_path);
+ EXPECT_FALSE(GetRootPath(manager.get(),
+ GURL(kRootPathTestCases[i].origin_url),
+ kRootPathTestCases[i].type,
+ false /* create */, NULL));
+ }
+}
+
+TEST_F(FileSystemPathManagerTest, GetRootPathInIncognito) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(
+ true /* incognito */, false));
+
+ // Try to get a root directory.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "RootPath (incognito) #" << i << " "
+ << kRootPathTestCases[i].expected_path);
+ EXPECT_FALSE(GetRootPath(manager.get(),
+ GURL(kRootPathTestCases[i].origin_url),
+ kRootPathTestCases[i].type,
+ true /* create */, NULL));
+ }
+}
+
+TEST_F(FileSystemPathManagerTest, GetRootPathFileURI) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathFileURITestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "RootPathFileURI (disallow) #"
+ << i << " " << kRootPathFileURITestCases[i].expected_path);
+ EXPECT_FALSE(GetRootPath(manager.get(),
+ GURL(kRootPathFileURITestCases[i].origin_url),
+ kRootPathFileURITestCases[i].type,
+ true /* create */, NULL));
+ }
+}
+
+TEST_F(FileSystemPathManagerTest, GetRootPathFileURIWithAllowFlag) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(
+ false, true /* allow_file_access_from_files */));
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathFileURITestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "RootPathFileURI (allow) #"
+ << i << " " << kRootPathFileURITestCases[i].expected_path);
+ FilePath root_path;
+ EXPECT_TRUE(GetRootPath(manager.get(),
+ GURL(kRootPathFileURITestCases[i].origin_url),
+ kRootPathFileURITestCases[i].type,
+ true /* create */, &root_path));
+ FilePath expected = file_system_path().AppendASCII(
+ kRootPathFileURITestCases[i].expected_path);
+ EXPECT_EQ(expected.value(), root_path.DirName().value());
+ EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ }
+}
+
+TEST_F(FileSystemPathManagerTest, VirtualPathFromFileSystemPathTest) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
+ FilePath root_path;
+ EXPECT_TRUE(GetRootPath(manager.get(), GURL("http://foo.com/"),
+ fileapi::kFileSystemTypeTemporary,
+ true /* create */, &root_path));
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kPathToVirtualPathTestCases); ++i) {
+ SCOPED_TRACE(testing::Message() << "PathToVirtualPath #"
+ << i << " " << kPathToVirtualPathTestCases[i]);
+ FilePath absolute_path = root_path.AppendASCII(
+ kPathToVirtualPathTestCases[i]);
+ FilePath virtual_path;
+ EXPECT_TRUE(manager->CrackFileSystemPath(absolute_path, NULL, NULL,
+ &virtual_path));
+
+ FilePath test_case_path;
+ test_case_path = test_case_path.AppendASCII(
+ kPathToVirtualPathTestCases[i]);
+ EXPECT_EQ(test_case_path.value(), virtual_path.value());
+ }
+}
+
+TEST_F(FileSystemPathManagerTest, TypeFromFileSystemPathTest) {
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
+
+ FilePath root_path;
+ fileapi::FileSystemType type;
+
+ EXPECT_TRUE(GetRootPath(manager.get(), GURL("http://foo.com/"),
+ fileapi::kFileSystemTypeTemporary,
+ true /* create */, &root_path));
+ FilePath path = root_path.AppendASCII("test");
+ EXPECT_TRUE(manager->CrackFileSystemPath(path, NULL, &type, NULL));
+ EXPECT_EQ(fileapi::kFileSystemTypeTemporary, type);
+
+ EXPECT_TRUE(GetRootPath(manager.get(), GURL("http://foo.com/"),
+ fileapi::kFileSystemTypePersistent,
+ true /* create */, &root_path));
+ path = root_path.AppendASCII("test");
+ EXPECT_TRUE(manager->CrackFileSystemPath(path, NULL, &type, NULL));
+ EXPECT_EQ(fileapi::kFileSystemTypePersistent, type);
+}
+
TEST_F(FileSystemPathManagerTest, CheckValidPath) {
- FileSystemPathManager* manager = GetNewPathManager(false);
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
FilePath root_path;
- EXPECT_TRUE(manager->GetFileSystemRootPath(
- GURL("http://foo.com/"), fileapi::kFileSystemTypePersistent,
- &root_path, NULL));
+ EXPECT_TRUE(GetRootPath(manager.get(), GURL("http://foo.com/"),
+ kFileSystemTypePersistent, true, &root_path));
// The root path must be valid, but upper directories or directories
// that are not in our temporary or persistent directory must be
// evaluated invalid.
- EXPECT_TRUE(manager->CheckValidFileSystemPath(root_path));
- EXPECT_FALSE(manager->CheckValidFileSystemPath(root_path.DirName()));
- EXPECT_FALSE(manager->CheckValidFileSystemPath(
- root_path.DirName().DirName()));
- EXPECT_FALSE(manager->CheckValidFileSystemPath(
- root_path.DirName().AppendASCII("ArbitraryName")));
+ EXPECT_TRUE(CheckValidFileSystemPath(manager.get(), root_path));
+ EXPECT_FALSE(CheckValidFileSystemPath(manager.get(), root_path.DirName()));
+ EXPECT_FALSE(CheckValidFileSystemPath(manager.get(),
+ root_path.DirName().DirName()));
+ EXPECT_FALSE(CheckValidFileSystemPath(manager.get(),
+ root_path.DirName().DirName()
+ .AppendASCII("ArbitraryName")
+ .AppendASCII("chrome-dummy")));
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckValidPathTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "CheckValidPath #" << i << " "
@@ -192,12 +410,12 @@ TEST_F(FileSystemPathManagerTest, CheckValidPath) {
if (!path.IsAbsolute())
path = root_path.Append(path);
EXPECT_EQ(kCheckValidPathTestCases[i].expected_valid,
- manager->CheckValidFileSystemPath(path));
+ CheckValidFileSystemPath(manager.get(), path));
}
}
TEST_F(FileSystemPathManagerTest, IsRestrictedName) {
- FileSystemPathManager* manager = GetNewPathManager(false);
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIsRestrictedNameTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "IsRestrictedName #" << i << " "
<< kIsRestrictedNameTestCases[i].name);
diff --git a/webkit/fileapi/file_system_types.h b/webkit/fileapi/file_system_types.h
index 5229f52..043e3a2 100644
--- a/webkit/fileapi/file_system_types.h
+++ b/webkit/fileapi/file_system_types.h
@@ -10,6 +10,7 @@ namespace fileapi {
enum FileSystemType {
kFileSystemTypeTemporary,
kFileSystemTypePersistent,
+ kFileSystemTypeUnknown,
};
}