OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 5 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
18 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
19 #include "webkit/fileapi/file_system_operation_context.h" | 19 #include "webkit/fileapi/file_system_operation_context.h" |
20 #include "webkit/fileapi/file_system_path_manager.h" | 20 #include "webkit/fileapi/file_system_options.h" |
21 #include "webkit/fileapi/file_system_types.h" | 21 #include "webkit/fileapi/file_system_types.h" |
22 #include "webkit/fileapi/file_system_usage_cache.h" | 22 #include "webkit/fileapi/file_system_usage_cache.h" |
23 #include "webkit/fileapi/file_system_util.h" | 23 #include "webkit/fileapi/file_system_util.h" |
24 #include "webkit/fileapi/obfuscated_file_util.h" | 24 #include "webkit/fileapi/obfuscated_file_util.h" |
25 #include "webkit/fileapi/quota_file_util.h" | 25 #include "webkit/fileapi/quota_file_util.h" |
26 #include "webkit/glue/webkit_glue.h" | 26 #include "webkit/glue/webkit_glue.h" |
27 #include "webkit/quota/quota_manager.h" | 27 #include "webkit/quota/quota_manager.h" |
28 | 28 |
29 using quota::QuotaManagerProxy; | 29 using quota::QuotaManagerProxy; |
30 | 30 |
31 namespace { | 31 namespace { |
32 | 32 |
33 static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = | 33 const char kChromeScheme[] = "chrome"; |
| 34 const char kExtensionScheme[] = "chrome-extension"; |
| 35 |
| 36 const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = |
34 FILE_PATH_LITERAL("chrome-"); | 37 FILE_PATH_LITERAL("chrome-"); |
35 static const int kOldFileSystemUniqueLength = 16; | 38 const size_t kOldFileSystemUniqueLength = 16; |
36 static const unsigned kOldFileSystemUniqueDirectoryNameLength = | 39 const size_t kOldFileSystemUniqueDirectoryNameLength = |
37 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1; | 40 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1; |
38 | 41 |
39 const char kOpenFileSystem[] = "FileSystem.OpenFileSystem"; | 42 const char kOpenFileSystem[] = "FileSystem.OpenFileSystem"; |
40 enum FileSystemError { | 43 enum FileSystemError { |
41 kOK = 0, | 44 kOK = 0, |
42 kIncognito, | 45 kIncognito, |
43 kInvalidScheme, | 46 kInvalidScheme, |
44 kCreateDirectoryError, | 47 kCreateDirectoryError, |
45 kFileSystemErrorMax, | 48 kFileSystemErrorMax, |
46 }; | 49 }; |
47 | 50 |
48 // Restricted names. | 51 // Restricted names. |
49 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions | 52 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions |
50 static const char* const kRestrictedNames[] = { | 53 const FilePath::CharType* const kRestrictedNames[] = { |
51 ".", "..", | 54 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."), |
52 }; | 55 }; |
53 | 56 |
54 // Restricted chars. | 57 // Restricted chars. |
55 static const FilePath::CharType kRestrictedChars[] = { | 58 const FilePath::CharType kRestrictedChars[] = { |
56 '/', '\\', | 59 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'), |
57 }; | 60 }; |
58 | 61 |
59 inline std::string FilePathStringToASCII( | |
60 const FilePath::StringType& path_string) { | |
61 #if defined(OS_WIN) | |
62 return WideToASCII(path_string); | |
63 #elif defined(OS_POSIX) | |
64 return path_string; | |
65 #endif | |
66 } | |
67 | |
68 FilePath::StringType OldCreateUniqueDirectoryName(const GURL& origin_url) { | 62 FilePath::StringType OldCreateUniqueDirectoryName(const GURL& origin_url) { |
69 // This can be anything but need to be unpredictable. | 63 // This can be anything but need to be unpredictable. |
70 static const FilePath::CharType letters[] = FILE_PATH_LITERAL( | 64 static const FilePath::CharType letters[] = FILE_PATH_LITERAL( |
71 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); | 65 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); |
72 FilePath::StringType unique(kOldFileSystemUniqueNamePrefix); | 66 FilePath::StringType unique(kOldFileSystemUniqueNamePrefix); |
73 for (int i = 0; i < kOldFileSystemUniqueLength; ++i) | 67 for (size_t i = 0; i < kOldFileSystemUniqueLength; ++i) |
74 unique += letters[base::RandInt(0, arraysize(letters) - 2)]; | 68 unique += letters[base::RandInt(0, arraysize(letters) - 2)]; |
75 return unique; | 69 return unique; |
76 } | 70 } |
77 | 71 |
78 base::PlatformFileError OldReadOriginDirectory(const FilePath& base_path, | 72 base::PlatformFileError OldReadOriginDirectory(const FilePath& base_path, |
79 FilePath* unique) { | 73 FilePath* unique) { |
80 file_util::FileEnumerator file_enum( | 74 file_util::FileEnumerator file_enum( |
81 base_path, false /* recursive */, | 75 base_path, false /* recursive */, |
82 file_util::FileEnumerator::DIRECTORIES, | 76 file_util::FileEnumerator::DIRECTORIES, |
83 FilePath::StringType(kOldFileSystemUniqueNamePrefix) + | 77 FilePath::StringType(kOldFileSystemUniqueNamePrefix) + |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 explicit OldSandboxOriginEnumerator(const FilePath& base_path) | 122 explicit OldSandboxOriginEnumerator(const FilePath& base_path) |
129 : enumerator_(base_path, false /* recursive */, | 123 : enumerator_(base_path, false /* recursive */, |
130 file_util::FileEnumerator::DIRECTORIES) {} | 124 file_util::FileEnumerator::DIRECTORIES) {} |
131 virtual ~OldSandboxOriginEnumerator() {} | 125 virtual ~OldSandboxOriginEnumerator() {} |
132 | 126 |
133 virtual GURL Next() OVERRIDE { | 127 virtual GURL Next() OVERRIDE { |
134 current_ = enumerator_.Next(); | 128 current_ = enumerator_.Next(); |
135 if (current_.empty()) | 129 if (current_.empty()) |
136 return GURL(); | 130 return GURL(); |
137 return fileapi::GetOriginURLFromIdentifier( | 131 return fileapi::GetOriginURLFromIdentifier( |
138 FilePathStringToASCII(current_.BaseName().value())); | 132 current_.BaseName().MaybeAsASCII()); |
139 } | 133 } |
140 | 134 |
141 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { | 135 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { |
142 if (current_.empty()) | 136 if (current_.empty()) |
143 return false; | 137 return false; |
144 std::string directory = | 138 std::string directory = GetFileSystemTypeString(type); |
145 fileapi::FileSystemPathManager::GetFileSystemTypeString(type); | |
146 DCHECK(!directory.empty()); | 139 DCHECK(!directory.empty()); |
147 return file_util::DirectoryExists(current_.AppendASCII(directory)); | 140 return file_util::DirectoryExists(current_.AppendASCII(directory)); |
148 } | 141 } |
149 | 142 |
150 private: | 143 private: |
151 file_util::FileEnumerator enumerator_; | 144 file_util::FileEnumerator enumerator_; |
152 FilePath current_; | 145 FilePath current_; |
153 }; | 146 }; |
154 | 147 |
155 FilePath OldGetBaseDirectoryForOrigin( | 148 FilePath OldGetBaseDirectoryForOrigin( |
156 const FilePath& old_base_path, | 149 const FilePath& old_base_path, |
157 const GURL& origin_url) { | 150 const GURL& origin_url) { |
158 std::string id = fileapi::GetOriginIdentifierFromURL(origin_url); | 151 std::string id = fileapi::GetOriginIdentifierFromURL(origin_url); |
159 if (!id.empty()) | 152 if (!id.empty()) |
160 return old_base_path.AppendASCII(id); | 153 return old_base_path.AppendASCII(id); |
161 return FilePath(); | 154 return FilePath(); |
162 } | 155 } |
163 | 156 |
164 FilePath OldGetBaseDirectoryForOriginAndType( | 157 FilePath OldGetBaseDirectoryForOriginAndType( |
165 const FilePath& old_base_path, | 158 const FilePath& old_base_path, |
166 const GURL& origin_url, fileapi::FileSystemType type) { | 159 const GURL& origin_url, fileapi::FileSystemType type) { |
167 std::string type_string = | 160 std::string type_string = GetFileSystemTypeString(type); |
168 fileapi::FileSystemPathManager::GetFileSystemTypeString(type); | |
169 if (type_string.empty()) { | 161 if (type_string.empty()) { |
170 NOTREACHED(); | 162 NOTREACHED(); |
171 return FilePath(); | 163 return FilePath(); |
172 } | 164 } |
173 FilePath base_path = OldGetBaseDirectoryForOrigin( | 165 FilePath base_path = OldGetBaseDirectoryForOrigin( |
174 old_base_path, origin_url); | 166 old_base_path, origin_url); |
175 if (base_path.empty()) { | 167 if (base_path.empty()) { |
176 NOTREACHED(); | 168 NOTREACHED(); |
177 return FilePath(); | 169 return FilePath(); |
178 } | 170 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 class SandboxMountPointProvider::GetFileSystemRootPathTask | 273 class SandboxMountPointProvider::GetFileSystemRootPathTask |
282 : public base::RefCountedThreadSafe< | 274 : public base::RefCountedThreadSafe< |
283 SandboxMountPointProvider::GetFileSystemRootPathTask> { | 275 SandboxMountPointProvider::GetFileSystemRootPathTask> { |
284 public: | 276 public: |
285 GetFileSystemRootPathTask( | 277 GetFileSystemRootPathTask( |
286 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 278 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
287 const GURL& origin_url, | 279 const GURL& origin_url, |
288 FileSystemType type, | 280 FileSystemType type, |
289 ObfuscatedFileUtil* file_util, | 281 ObfuscatedFileUtil* file_util, |
290 const FilePath& old_base_path, | 282 const FilePath& old_base_path, |
291 const FileSystemPathManager::GetRootPathCallback& callback) | 283 const FileSystemMountPointProvider::GetRootPathCallback& callback) |
292 : file_message_loop_(file_message_loop), | 284 : file_message_loop_(file_message_loop), |
293 origin_message_loop_proxy_( | 285 origin_message_loop_proxy_( |
294 base::MessageLoopProxy::current()), | 286 base::MessageLoopProxy::current()), |
295 origin_url_(origin_url), | 287 origin_url_(origin_url), |
296 type_(type), | 288 type_(type), |
297 file_util_(file_util), | 289 file_util_(file_util), |
298 old_base_path_(old_base_path), | 290 old_base_path_(old_base_path), |
299 callback_(callback) { | 291 callback_(callback) { |
300 } | 292 } |
301 | 293 |
(...skipping 28 matching lines...) Expand all Loading... |
330 kFileSystemErrorMax); | 322 kFileSystemErrorMax); |
331 } | 323 } |
332 origin_message_loop_proxy_->PostTask( | 324 origin_message_loop_proxy_->PostTask( |
333 FROM_HERE, | 325 FROM_HERE, |
334 base::Bind(&GetFileSystemRootPathTask::DispatchCallback, this, | 326 base::Bind(&GetFileSystemRootPathTask::DispatchCallback, this, |
335 root_path)); | 327 root_path)); |
336 } | 328 } |
337 | 329 |
338 void DispatchCallback(const FilePath& root_path) { | 330 void DispatchCallback(const FilePath& root_path) { |
339 std::string origin_identifier = GetOriginIdentifierFromURL(origin_url_); | 331 std::string origin_identifier = GetOriginIdentifierFromURL(origin_url_); |
340 std::string type_string = | 332 std::string type_string = GetFileSystemTypeString(type_); |
341 FileSystemPathManager::GetFileSystemTypeString(type_); | |
342 DCHECK(!type_string.empty()); | 333 DCHECK(!type_string.empty()); |
343 std::string name = origin_identifier + ":" + type_string; | 334 std::string name = origin_identifier + ":" + type_string; |
344 | 335 |
345 if (!root_path.empty()) | 336 if (!root_path.empty()) |
346 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax); | 337 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax); |
347 | 338 |
348 callback_.Run(!root_path.empty(), root_path, name); | 339 callback_.Run(!root_path.empty(), root_path, name); |
349 callback_.Reset(); | 340 callback_.Reset(); |
350 } | 341 } |
351 | 342 |
352 scoped_refptr<base::MessageLoopProxy> file_message_loop_; | 343 scoped_refptr<base::MessageLoopProxy> file_message_loop_; |
353 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | 344 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; |
354 GURL origin_url_; | 345 GURL origin_url_; |
355 FileSystemType type_; | 346 FileSystemType type_; |
356 scoped_refptr<ObfuscatedFileUtil> file_util_; | 347 scoped_refptr<ObfuscatedFileUtil> file_util_; |
357 FilePath old_base_path_; | 348 FilePath old_base_path_; |
358 FileSystemPathManager::GetRootPathCallback callback_; | 349 FileSystemMountPointProvider::GetRootPathCallback callback_; |
359 }; | 350 }; |
360 | 351 |
361 SandboxMountPointProvider::SandboxMountPointProvider( | 352 SandboxMountPointProvider::SandboxMountPointProvider( |
362 FileSystemPathManager* path_manager, | |
363 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 353 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
364 const FilePath& profile_path) | 354 const FilePath& profile_path, |
| 355 const FileSystemOptions& file_system_options) |
365 : FileSystemQuotaUtil(file_message_loop), | 356 : FileSystemQuotaUtil(file_message_loop), |
366 path_manager_(path_manager), | |
367 file_message_loop_(file_message_loop), | 357 file_message_loop_(file_message_loop), |
368 profile_path_(profile_path), | 358 profile_path_(profile_path), |
| 359 file_system_options_(file_system_options), |
369 sandbox_file_util_( | 360 sandbox_file_util_( |
370 new ObfuscatedFileUtil( | 361 new ObfuscatedFileUtil( |
371 profile_path.Append(kNewFileSystemDirectory), | 362 profile_path.Append(kNewFileSystemDirectory), |
372 QuotaFileUtil::CreateDefault())) { | 363 QuotaFileUtil::CreateDefault())) { |
373 } | 364 } |
374 | 365 |
375 SandboxMountPointProvider::~SandboxMountPointProvider() { | 366 SandboxMountPointProvider::~SandboxMountPointProvider() { |
376 if (!file_message_loop_->BelongsToCurrentThread()) | 367 if (!file_message_loop_->BelongsToCurrentThread()) |
377 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); | 368 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); |
378 } | 369 } |
379 | 370 |
380 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, | 371 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, |
381 FileSystemType type, | 372 FileSystemType type, |
382 const FilePath& unused) { | 373 const FilePath& unused) { |
383 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) | 374 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) |
384 return false; | 375 return false; |
385 // We essentially depend on quota to do our access controls. | 376 // We essentially depend on quota to do our access controls, so here |
386 return path_manager_->IsAllowedScheme(origin_url); | 377 // we only check if the requested scheme is allowed or not. |
| 378 return IsAllowedScheme(origin_url); |
387 } | 379 } |
388 | 380 |
389 void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL( | 381 void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL( |
390 const GURL& origin_url, fileapi::FileSystemType type, bool create, | 382 const GURL& origin_url, fileapi::FileSystemType type, bool create, |
391 const FileSystemPathManager::GetRootPathCallback& callback) { | 383 const FileSystemMountPointProvider::GetRootPathCallback& callback) { |
392 FilePath origin_base_path; | 384 FilePath origin_base_path; |
393 | 385 |
394 if (path_manager_->is_incognito()) { | 386 if (file_system_options_.is_incognito()) { |
395 // TODO(kinuko): return an isolated temporary directory. | 387 // TODO(kinuko): return an isolated temporary directory. |
396 callback.Run(false, FilePath(), std::string()); | 388 callback.Run(false, FilePath(), std::string()); |
397 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, | 389 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, |
398 kIncognito, | 390 kIncognito, |
399 kFileSystemErrorMax); | 391 kFileSystemErrorMax); |
400 return; | 392 return; |
401 } | 393 } |
402 | 394 |
403 if (!path_manager_->IsAllowedScheme(origin_url)) { | 395 if (!IsAllowedScheme(origin_url)) { |
404 callback.Run(false, FilePath(), std::string()); | 396 callback.Run(false, FilePath(), std::string()); |
405 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, | 397 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, |
406 kInvalidScheme, | 398 kInvalidScheme, |
407 kFileSystemErrorMax); | 399 kFileSystemErrorMax); |
408 return; | 400 return; |
409 } | 401 } |
410 | 402 |
411 scoped_refptr<GetFileSystemRootPathTask> task( | 403 scoped_refptr<GetFileSystemRootPathTask> task( |
412 new GetFileSystemRootPathTask( | 404 new GetFileSystemRootPathTask( |
413 file_message_loop_, origin_url, type, sandbox_file_util_.get(), | 405 file_message_loop_, origin_url, type, sandbox_file_util_.get(), |
414 old_base_path(), callback)); | 406 old_base_path(), callback)); |
415 task->Start(create); | 407 task->Start(create); |
416 }; | 408 }; |
417 | 409 |
418 FilePath | 410 FilePath |
419 SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread( | 411 SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread( |
420 const GURL& origin_url, FileSystemType type, const FilePath& unused, | 412 const GURL& origin_url, FileSystemType type, const FilePath& unused, |
421 bool create) { | 413 bool create) { |
422 if (path_manager_->is_incognito()) | 414 if (file_system_options_.is_incognito()) |
423 // TODO(kinuko): return an isolated temporary directory. | 415 // TODO(kinuko): return an isolated temporary directory. |
424 return FilePath(); | 416 return FilePath(); |
425 | 417 |
426 if (!path_manager_->IsAllowedScheme(origin_url)) | 418 if (!IsAllowedScheme(origin_url)) |
427 return FilePath(); | 419 return FilePath(); |
428 | 420 |
429 MigrateIfNeeded(sandbox_file_util_, old_base_path()); | 421 MigrateIfNeeded(sandbox_file_util_, old_base_path()); |
430 | 422 |
431 return sandbox_file_util_->GetDirectoryForOriginAndType( | 423 return sandbox_file_util_->GetDirectoryForOriginAndType( |
432 origin_url, type, create); | 424 origin_url, type, create); |
433 } | 425 } |
434 | 426 |
435 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename) | 427 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename) |
436 const { | 428 const { |
437 if (filename.value().empty()) | 429 if (filename.value().empty()) |
438 return false; | 430 return false; |
439 | 431 |
440 std::string filename_lower = StringToLowerASCII( | |
441 FilePathStringToASCII(filename.value())); | |
442 | |
443 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { | 432 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { |
444 // Exact match. | 433 // Exact match. |
445 if (filename_lower == kRestrictedNames[i]) | 434 if (filename.value() == kRestrictedNames[i]) |
446 return true; | 435 return true; |
447 } | 436 } |
448 | 437 |
449 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { | 438 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { |
450 if (filename.value().find(kRestrictedChars[i]) != | 439 if (filename.value().find(kRestrictedChars[i]) != |
451 FilePath::StringType::npos) | 440 FilePath::StringType::npos) |
452 return true; | 441 return true; |
453 } | 442 } |
454 | 443 |
455 return false; | 444 return false; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 return FilePath(); | 659 return FilePath(); |
671 | 660 |
672 // Creates the root directory. | 661 // Creates the root directory. |
673 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); | 662 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); |
674 if (!file_util::CreateDirectory(root)) | 663 if (!file_util::CreateDirectory(root)) |
675 return FilePath(); | 664 return FilePath(); |
676 | 665 |
677 return root; | 666 return root; |
678 } | 667 } |
679 | 668 |
| 669 bool SandboxMountPointProvider::IsAllowedScheme(const GURL& url) const { |
| 670 // Basically we only accept http or https. We allow file:// URLs |
| 671 // only if --allow-file-access-from-files flag is given. |
| 672 if (url.SchemeIs("http") || url.SchemeIs("https")) |
| 673 return true; |
| 674 for (size_t i = 0; |
| 675 i < file_system_options_.additional_allowed_schemes().size(); |
| 676 ++i) { |
| 677 if (url.SchemeIs( |
| 678 file_system_options_.additional_allowed_schemes()[i].c_str())) |
| 679 return true; |
| 680 } |
| 681 return false; |
| 682 } |
| 683 |
680 } // namespace fileapi | 684 } // namespace fileapi |
OLD | NEW |