15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/strings/string_util.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/base/escape.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_types.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL::FileSystemURL()
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_valid_(false),
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_type_(kFileSystemTypeUnknown),
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      type_(kFileSystemTypeUnknown),
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemURL::CreateForTest(const GURL& url) {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FileSystemURL(url);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL FileSystemURL::CreateForTest(const GURL& origin,
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                           FileSystemType mount_type,
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                           const base::FilePath& virtual_path) {
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return FileSystemURL(origin, mount_type, virtual_path);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFileSystemURL FileSystemURL::CreateForTest(
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& origin,
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FileSystemType mount_type,
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& virtual_path,
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& mount_filesystem_id,
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FileSystemType cracked_type,
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& cracked_path,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& filesystem_id,
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const FileSystemMountOption& mount_option) {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return FileSystemURL(origin,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       mount_type,
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       virtual_path,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       mount_filesystem_id,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       cracked_type,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       cracked_path,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       filesystem_id,
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       mount_option);
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemURL::FileSystemURL(const GURL& url)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : mount_type_(kFileSystemTypeUnknown),
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      type_(kFileSystemTypeUnknown),
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_,
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                       &virtual_path_);
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  path_ = virtual_path_;
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  type_ = mount_type_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL::FileSystemURL(const GURL& origin,
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                             FileSystemType mount_type,
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                             const base::FilePath& virtual_path)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_valid_(true),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin_(origin),
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      mount_type_(mount_type),
74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      virtual_path_(virtual_path.NormalizePathSeparators()),
75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      type_(mount_type),
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      path_(virtual_path.NormalizePathSeparators()),
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      mount_option_(COPY_SYNC_OPTION_NO_SYNC) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL::FileSystemURL(const GURL& origin,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FileSystemType mount_type,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const base::FilePath& virtual_path,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& mount_filesystem_id,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FileSystemType cracked_type,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const base::FilePath& cracked_path,
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const std::string& filesystem_id,
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const FileSystemMountOption& mount_option)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : is_valid_(true),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      origin_(origin),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_type_(mount_type),
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      virtual_path_(virtual_path.NormalizePathSeparators()),
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_filesystem_id_(mount_filesystem_id),
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type_(cracked_type),
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      path_(cracked_path.NormalizePathSeparators()),
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      filesystem_id_(filesystem_id),
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      mount_option_(mount_option) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemURL::~FileSystemURL() {}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)GURL FileSystemURL::ToGURL() const {
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!is_valid_)
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return GURL();
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::string url = GetFileSystemRootURI(origin_, mount_type_).spec();
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (url.empty())
107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return GURL();
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Exactly match with DOMFileSystemBase::createFileSystemURL()'s encoding
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // behavior, where the path is escaped by KURL::encodeWithURLEscapeSequences
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // which is essentially encodeURIComponent except '/'.
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string escaped = net::EscapeQueryParamValue(
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      virtual_path_.NormalizePathSeparatorsTo('/').AsUTF8Unsafe(),
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      false /* use_plus */);
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ReplaceSubstringsAfterOffset(&escaped, 0, "%2F", "/");
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  url.append(escaped);
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Build nested GURL.
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return GURL(url);
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string FileSystemURL::DebugString() const {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_valid_)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return "invalid filesystem: URL";
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream ss;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ss << GetFileSystemRootURI(origin_, mount_type_);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // filesystem_id_ will be non empty for (and only for) cracked URLs.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!filesystem_id_.empty()) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << virtual_path_.value();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << " (";
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << path_.value();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss << ")";
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << path_.value();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ss.str();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSystemURL::IsParent(const FileSystemURL& child) const {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return IsInSameFileSystem(child) &&
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         path().IsParent(child.path());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const {
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return origin() == other.origin() &&
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         type() == other.type() &&
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         filesystem_id() == other.filesystem_id();
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSystemURL::operator==(const FileSystemURL& that) const {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return origin_ == that.origin_ &&
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type_ == that.type_ &&
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path_ == that.path_ &&
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filesystem_id_ == that.filesystem_id_ &&
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_valid_ == that.is_valid_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const FileSystemURL& rhs) const {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(lhs.is_valid_ && rhs.is_valid_);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (lhs.origin_ != rhs.origin_)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return lhs.origin_ < rhs.origin_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (lhs.type_ != rhs.type_)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return lhs.type_ < rhs.type_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (lhs.filesystem_id_ != rhs.filesystem_id_)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return lhs.filesystem_id_ < rhs.filesystem_id_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return lhs.path_ < rhs.path_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
173