[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "webkit/fileapi/file_system_url.h" |
| 6 | |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 7 | #include <sstream> |
| 8 | |
[email protected] | bf2d3f9 | 2012-09-10 17:14:14 | [diff] [blame] | 9 | #include "base/logging.h" |
[email protected] | 3e4ec1b | 2012-09-05 06:45:53 | [diff] [blame] | 10 | #include "base/string_util.h" |
| 11 | #include "net/base/escape.h" |
[email protected] | 9d5d698 | 2013-01-18 03:12:54 | [diff] [blame] | 12 | #include "webkit/fileapi/external_mount_points.h" |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 13 | #include "webkit/fileapi/file_system_types.h" |
| 14 | #include "webkit/fileapi/file_system_util.h" |
[email protected] | d6afd11 | 2012-07-25 22:55:04 | [diff] [blame] | 15 | #include "webkit/fileapi/isolated_context.h" |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 16 | |
| 17 | namespace fileapi { |
[email protected] | 8f69789 | 2012-10-09 07:18:49 | [diff] [blame] | 18 | |
[email protected] | 3e4ec1b | 2012-09-05 06:45:53 | [diff] [blame] | 19 | namespace { |
[email protected] | 8f69789 | 2012-10-09 07:18:49 | [diff] [blame] | 20 | |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 21 | bool ParseFileSystemURL(const GURL& url, |
| 22 | GURL* origin_url, |
| 23 | FileSystemType* type, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 24 | base::FilePath* file_path) { |
[email protected] | 3e4ec1b | 2012-09-05 06:45:53 | [diff] [blame] | 25 | GURL origin; |
| 26 | FileSystemType file_system_type = kFileSystemTypeUnknown; |
| 27 | |
| 28 | if (!url.is_valid() || !url.SchemeIsFileSystem()) |
| 29 | return false; |
| 30 | DCHECK(url.inner_url()); |
| 31 | |
| 32 | std::string inner_path = url.inner_url()->path(); |
| 33 | |
| 34 | const struct { |
| 35 | FileSystemType type; |
| 36 | const char* dir; |
| 37 | } kValidTypes[] = { |
| 38 | { kFileSystemTypePersistent, kPersistentDir }, |
| 39 | { kFileSystemTypeTemporary, kTemporaryDir }, |
| 40 | { kFileSystemTypeIsolated, kIsolatedDir }, |
| 41 | { kFileSystemTypeExternal, kExternalDir }, |
| 42 | { kFileSystemTypeTest, kTestDir }, |
| 43 | }; |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 44 | |
[email protected] | 3e4ec1b | 2012-09-05 06:45:53 | [diff] [blame] | 45 | for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) { |
| 46 | if (StartsWithASCII(inner_path, kValidTypes[i].dir, true)) { |
| 47 | file_system_type = kValidTypes[i].type; |
| 48 | break; |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | if (file_system_type == kFileSystemTypeUnknown) |
| 53 | return false; |
| 54 | |
| 55 | std::string path = net::UnescapeURLComponent(url.path(), |
| 56 | net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS | |
| 57 | net::UnescapeRule::CONTROL_CHARS); |
| 58 | |
| 59 | // Ensure the path is relative. |
| 60 | while (!path.empty() && path[0] == '/') |
| 61 | path.erase(0, 1); |
| 62 | |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 63 | base::FilePath converted_path = base::FilePath::FromUTF8Unsafe(path); |
[email protected] | 3e4ec1b | 2012-09-05 06:45:53 | [diff] [blame] | 64 | |
| 65 | // All parent references should have been resolved in the renderer. |
| 66 | if (converted_path.ReferencesParent()) |
| 67 | return false; |
| 68 | |
| 69 | if (origin_url) |
| 70 | *origin_url = url.GetOrigin(); |
| 71 | if (type) |
| 72 | *type = file_system_type; |
| 73 | if (file_path) |
| 74 | *file_path = converted_path.NormalizePathSeparators(). |
| 75 | StripTrailingSeparators(); |
| 76 | |
| 77 | return true; |
| 78 | } |
| 79 | |
| 80 | } // namespace |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 81 | |
| 82 | FileSystemURL::FileSystemURL() |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 83 | : is_valid_(false), |
| 84 | type_(kFileSystemTypeUnknown), |
| 85 | mount_type_(kFileSystemTypeUnknown) { |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 86 | } |
| 87 | |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 88 | // static |
| 89 | FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { |
| 90 | return FileSystemURL(url); |
| 91 | } |
| 92 | |
| 93 | FileSystemURL FileSystemURL::CreateForTest(const GURL& origin, |
| 94 | FileSystemType type, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 95 | const base::FilePath& path) { |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 96 | return FileSystemURL(origin, type, path); |
| 97 | } |
| 98 | |
| 99 | FileSystemURL::FileSystemURL(const GURL& url) |
| 100 | : type_(kFileSystemTypeUnknown), |
| 101 | mount_type_(kFileSystemTypeUnknown) { |
| 102 | is_valid_ = ParseFileSystemURL(url, &origin_, &type_, &path_); |
| 103 | mount_type_ = type_; |
| 104 | } |
| 105 | |
| 106 | FileSystemURL::FileSystemURL(const GURL& origin, |
| 107 | FileSystemType type, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 108 | const base::FilePath& path) |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 109 | : is_valid_(true), |
| 110 | origin_(origin), |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 111 | type_(type), |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 112 | mount_type_(type), |
| 113 | path_(path.NormalizePathSeparators()) { |
| 114 | } |
| 115 | |
| 116 | FileSystemURL::FileSystemURL(const GURL& origin, |
| 117 | FileSystemType original_type, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 118 | const base::FilePath& original_path, |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 119 | const std::string& filesystem_id, |
| 120 | FileSystemType cracked_type, |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 121 | const base::FilePath& cracked_path) |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 122 | : is_valid_(true), |
| 123 | origin_(origin), |
| 124 | type_(cracked_type), |
| 125 | mount_type_(original_type), |
| 126 | path_(cracked_path.NormalizePathSeparators()), |
| 127 | filesystem_id_(filesystem_id), |
| 128 | virtual_path_(original_path.NormalizePathSeparators()) { |
[email protected] | d6afd11 | 2012-07-25 22:55:04 | [diff] [blame] | 129 | } |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 130 | |
| 131 | FileSystemURL::~FileSystemURL() {} |
| 132 | |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 133 | std::string FileSystemURL::DebugString() const { |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 134 | if (!is_valid_) |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 135 | return "invalid filesystem: URL"; |
| 136 | std::ostringstream ss; |
| 137 | ss << GetFileSystemRootURI(origin_, mount_type_); |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 138 | |
| 139 | // filesystem_id_ will be non empty for (and only for) cracked URLs. |
| 140 | if (!filesystem_id_.empty()) { |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 141 | ss << virtual_path_.value(); |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 142 | ss << " ("; |
| 143 | ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":"; |
| 144 | ss << path_.value(); |
| 145 | ss << ")"; |
[email protected] | 5b7e42e6 | 2013-01-24 22:01:51 | [diff] [blame] | 146 | } else { |
| 147 | ss << path_.value(); |
[email protected] | a349dd94 | 2012-10-15 16:09:13 | [diff] [blame] | 148 | } |
| 149 | return ss.str(); |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 150 | } |
| 151 | |
[email protected] | a3ef483 | 2013-02-02 05:12:33 | [diff] [blame^] | 152 | FileSystemURL FileSystemURL::WithPath(const base::FilePath& path) const { |
[email protected] | 8f69789 | 2012-10-09 07:18:49 | [diff] [blame] | 153 | FileSystemURL url = *this; |
| 154 | url.path_ = path; |
| 155 | url.virtual_path_.clear(); |
| 156 | return url; |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 157 | } |
| 158 | |
[email protected] | 5dca49e | 2012-10-10 14:56:13 | [diff] [blame] | 159 | bool FileSystemURL::IsParent(const FileSystemURL& child) const { |
| 160 | return origin() == child.origin() && |
| 161 | type() == child.type() && |
| 162 | filesystem_id() == child.filesystem_id() && |
| 163 | path().IsParent(child.path()); |
| 164 | } |
| 165 | |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 166 | bool FileSystemURL::operator==(const FileSystemURL& that) const { |
| 167 | return origin_ == that.origin_ && |
| 168 | type_ == that.type_ && |
| 169 | path_ == that.path_ && |
[email protected] | d6afd11 | 2012-07-25 22:55:04 | [diff] [blame] | 170 | filesystem_id_ == that.filesystem_id_ && |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 171 | is_valid_ == that.is_valid_; |
| 172 | } |
| 173 | |
[email protected] | bf2d3f9 | 2012-09-10 17:14:14 | [diff] [blame] | 174 | bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, |
| 175 | const FileSystemURL& rhs) const { |
| 176 | DCHECK(lhs.is_valid_ && rhs.is_valid_); |
| 177 | if (lhs.origin_ != rhs.origin_) |
| 178 | return lhs.origin_ < rhs.origin_; |
| 179 | if (lhs.type_ != rhs.type_) |
| 180 | return lhs.type_ < rhs.type_; |
[email protected] | 8f69789 | 2012-10-09 07:18:49 | [diff] [blame] | 181 | if (lhs.filesystem_id_ != rhs.filesystem_id_) |
| 182 | return lhs.filesystem_id_ < rhs.filesystem_id_; |
| 183 | return lhs.path_ < rhs.path_; |
[email protected] | bf2d3f9 | 2012-09-10 17:14:14 | [diff] [blame] | 184 | } |
| 185 | |
[email protected] | 949f25a | 2012-06-27 01:53:09 | [diff] [blame] | 186 | } // namespace fileapi |