blob: 5f38e53dabfdc318defd3230fd0955660b22f4bf [file] [log] [blame]
[email protected]949f25a2012-06-27 01:53:091// 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]a349dd942012-10-15 16:09:137#include <sstream>
8
[email protected]bf2d3f92012-09-10 17:14:149#include "base/logging.h"
[email protected]3e4ec1b2012-09-05 06:45:5310#include "base/string_util.h"
11#include "net/base/escape.h"
[email protected]9d5d6982013-01-18 03:12:5412#include "webkit/fileapi/external_mount_points.h"
[email protected]949f25a2012-06-27 01:53:0913#include "webkit/fileapi/file_system_types.h"
14#include "webkit/fileapi/file_system_util.h"
[email protected]d6afd112012-07-25 22:55:0415#include "webkit/fileapi/isolated_context.h"
[email protected]949f25a2012-06-27 01:53:0916
17namespace fileapi {
[email protected]8f697892012-10-09 07:18:4918
[email protected]3e4ec1b2012-09-05 06:45:5319namespace {
[email protected]8f697892012-10-09 07:18:4920
[email protected]5b7e42e62013-01-24 22:01:5121bool ParseFileSystemURL(const GURL& url,
22 GURL* origin_url,
23 FileSystemType* type,
[email protected]a3ef4832013-02-02 05:12:3324 base::FilePath* file_path) {
[email protected]3e4ec1b2012-09-05 06:45:5325 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]5b7e42e62013-01-24 22:01:5144
[email protected]3e4ec1b2012-09-05 06:45:5345 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]a3ef4832013-02-02 05:12:3363 base::FilePath converted_path = base::FilePath::FromUTF8Unsafe(path);
[email protected]3e4ec1b2012-09-05 06:45:5364
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]949f25a2012-06-27 01:53:0981
82FileSystemURL::FileSystemURL()
[email protected]5b7e42e62013-01-24 22:01:5183 : is_valid_(false),
84 type_(kFileSystemTypeUnknown),
85 mount_type_(kFileSystemTypeUnknown) {
[email protected]949f25a2012-06-27 01:53:0986}
87
[email protected]5b7e42e62013-01-24 22:01:5188// static
89FileSystemURL FileSystemURL::CreateForTest(const GURL& url) {
90 return FileSystemURL(url);
91}
92
93FileSystemURL FileSystemURL::CreateForTest(const GURL& origin,
94 FileSystemType type,
[email protected]a3ef4832013-02-02 05:12:3395 const base::FilePath& path) {
[email protected]5b7e42e62013-01-24 22:01:5196 return FileSystemURL(origin, type, path);
97}
98
99FileSystemURL::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
106FileSystemURL::FileSystemURL(const GURL& origin,
107 FileSystemType type,
[email protected]a3ef4832013-02-02 05:12:33108 const base::FilePath& path)
[email protected]5b7e42e62013-01-24 22:01:51109 : is_valid_(true),
110 origin_(origin),
[email protected]949f25a2012-06-27 01:53:09111 type_(type),
[email protected]5b7e42e62013-01-24 22:01:51112 mount_type_(type),
113 path_(path.NormalizePathSeparators()) {
114}
115
116FileSystemURL::FileSystemURL(const GURL& origin,
117 FileSystemType original_type,
[email protected]a3ef4832013-02-02 05:12:33118 const base::FilePath& original_path,
[email protected]5b7e42e62013-01-24 22:01:51119 const std::string& filesystem_id,
120 FileSystemType cracked_type,
[email protected]a3ef4832013-02-02 05:12:33121 const base::FilePath& cracked_path)
[email protected]5b7e42e62013-01-24 22:01:51122 : 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]d6afd112012-07-25 22:55:04129}
[email protected]949f25a2012-06-27 01:53:09130
131FileSystemURL::~FileSystemURL() {}
132
[email protected]a349dd942012-10-15 16:09:13133std::string FileSystemURL::DebugString() const {
[email protected]949f25a2012-06-27 01:53:09134 if (!is_valid_)
[email protected]a349dd942012-10-15 16:09:13135 return "invalid filesystem: URL";
136 std::ostringstream ss;
137 ss << GetFileSystemRootURI(origin_, mount_type_);
[email protected]5b7e42e62013-01-24 22:01:51138
139 // filesystem_id_ will be non empty for (and only for) cracked URLs.
140 if (!filesystem_id_.empty()) {
[email protected]a349dd942012-10-15 16:09:13141 ss << virtual_path_.value();
[email protected]a349dd942012-10-15 16:09:13142 ss << " (";
143 ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":";
144 ss << path_.value();
145 ss << ")";
[email protected]5b7e42e62013-01-24 22:01:51146 } else {
147 ss << path_.value();
[email protected]a349dd942012-10-15 16:09:13148 }
149 return ss.str();
[email protected]949f25a2012-06-27 01:53:09150}
151
[email protected]a3ef4832013-02-02 05:12:33152FileSystemURL FileSystemURL::WithPath(const base::FilePath& path) const {
[email protected]8f697892012-10-09 07:18:49153 FileSystemURL url = *this;
154 url.path_ = path;
155 url.virtual_path_.clear();
156 return url;
[email protected]949f25a2012-06-27 01:53:09157}
158
[email protected]5dca49e2012-10-10 14:56:13159bool 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]949f25a2012-06-27 01:53:09166bool FileSystemURL::operator==(const FileSystemURL& that) const {
167 return origin_ == that.origin_ &&
168 type_ == that.type_ &&
169 path_ == that.path_ &&
[email protected]d6afd112012-07-25 22:55:04170 filesystem_id_ == that.filesystem_id_ &&
[email protected]949f25a2012-06-27 01:53:09171 is_valid_ == that.is_valid_;
172}
173
[email protected]bf2d3f92012-09-10 17:14:14174bool 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]8f697892012-10-09 07:18:49181 if (lhs.filesystem_id_ != rhs.filesystem_id_)
182 return lhs.filesystem_id_ < rhs.filesystem_id_;
183 return lhs.path_ < rhs.path_;
[email protected]bf2d3f92012-09-10 17:14:14184}
185
[email protected]949f25a2012-06-27 01:53:09186} // namespace fileapi