OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser/fileapi/file_system_dir_url_request_job.h" | 5 #include "webkit/browser/fileapi/file_system_dir_url_request_job.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/file_util.h" |
9 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
10 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
11 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/memory/scoped_vector.h" |
12 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
13 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
14 #include "base/platform_file.h" | 16 #include "base/platform_file.h" |
15 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
16 #include "base/strings/string_piece.h" | 18 #include "base/strings/string_piece.h" |
17 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "content/public/test/test_file_system_backend.h" |
18 #include "content/public/test/test_file_system_context.h" | 21 #include "content/public/test/test_file_system_context.h" |
19 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
20 #include "net/base/net_util.h" | 23 #include "net/base/net_util.h" |
21 #include "net/base/request_priority.h" | 24 #include "net/base/request_priority.h" |
22 #include "net/http/http_request_headers.h" | 25 #include "net/http/http_request_headers.h" |
23 #include "net/url_request/url_request.h" | 26 #include "net/url_request/url_request.h" |
24 #include "net/url_request/url_request_context.h" | 27 #include "net/url_request/url_request_context.h" |
25 #include "net/url_request/url_request_test_util.h" | 28 #include "net/url_request/url_request_test_util.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
27 #include "third_party/icu/source/i18n/unicode/regex.h" | 30 #include "third_party/icu/source/i18n/unicode/regex.h" |
| 31 #include "webkit/browser/fileapi/external_mount_points.h" |
28 #include "webkit/browser/fileapi/file_system_context.h" | 32 #include "webkit/browser/fileapi/file_system_context.h" |
29 #include "webkit/browser/fileapi/file_system_file_util.h" | 33 #include "webkit/browser/fileapi/file_system_file_util.h" |
30 #include "webkit/browser/fileapi/file_system_operation_context.h" | 34 #include "webkit/browser/fileapi/file_system_operation_context.h" |
31 #include "webkit/browser/fileapi/file_system_url.h" | 35 #include "webkit/browser/fileapi/file_system_url.h" |
32 #include "webkit/browser/quota/mock_special_storage_policy.h" | 36 #include "webkit/browser/quota/mock_special_storage_policy.h" |
33 | 37 |
34 using fileapi::FileSystemContext; | 38 using fileapi::FileSystemContext; |
35 using fileapi::FileSystemOperationContext; | 39 using fileapi::FileSystemOperationContext; |
36 using fileapi::FileSystemURL; | 40 using fileapi::FileSystemURL; |
37 | 41 |
38 namespace content { | 42 namespace content { |
39 namespace { | 43 namespace { |
40 | 44 |
41 // We always use the TEMPORARY FileSystem in this test. | 45 // We always use the TEMPORARY FileSystem in this test. |
42 static const char kFileSystemURLPrefix[] = | 46 const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/"; |
43 "filesystem:http://remote/temporary/"; | 47 |
| 48 const char kValidExternalMountPoint[] = "mnt_name"; |
| 49 |
| 50 // An auto mounter that will try to mount anything for |storage_domain| = |
| 51 // "automount", but will only succeed for the mount point "mnt_name". |
| 52 bool TestAutoMountForURLRequest( |
| 53 const net::URLRequest* /*url_request*/, |
| 54 const fileapi::FileSystemURL& filesystem_url, |
| 55 const std::string& storage_domain, |
| 56 const base::Callback<void(base::File::Error result)>& callback) { |
| 57 if (storage_domain != "automount") |
| 58 return false; |
| 59 |
| 60 std::vector<base::FilePath::StringType> components; |
| 61 filesystem_url.path().GetComponents(&components); |
| 62 std::string mount_point = base::FilePath(components[0]).AsUTF8Unsafe(); |
| 63 |
| 64 if (mount_point == kValidExternalMountPoint) { |
| 65 fileapi::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( |
| 66 kValidExternalMountPoint, fileapi::kFileSystemTypeTest, |
| 67 fileapi::FileSystemMountOption(), base::FilePath()); |
| 68 callback.Run(base::File::FILE_OK); |
| 69 } else { |
| 70 callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
| 71 } |
| 72 return true; |
| 73 } |
44 | 74 |
45 } // namespace | 75 } // namespace |
46 | 76 |
47 class FileSystemDirURLRequestJobTest : public testing::Test { | 77 class FileSystemDirURLRequestJobTest : public testing::Test { |
48 protected: | 78 protected: |
49 FileSystemDirURLRequestJobTest() | 79 FileSystemDirURLRequestJobTest() |
50 : weak_factory_(this) { | 80 : weak_factory_(this) { |
51 } | 81 } |
52 | 82 |
53 virtual void SetUp() OVERRIDE { | 83 virtual void SetUp() OVERRIDE { |
(...skipping 16 matching lines...) Expand all Loading... |
70 | 100 |
71 virtual void TearDown() OVERRIDE { | 101 virtual void TearDown() OVERRIDE { |
72 // NOTE: order matters, request must die before delegate | 102 // NOTE: order matters, request must die before delegate |
73 request_.reset(NULL); | 103 request_.reset(NULL); |
74 delegate_.reset(NULL); | 104 delegate_.reset(NULL); |
75 | 105 |
76 net::URLRequest::Deprecated::RegisterProtocolFactory("filesystem", NULL); | 106 net::URLRequest::Deprecated::RegisterProtocolFactory("filesystem", NULL); |
77 ClearUnusedJob(); | 107 ClearUnusedJob(); |
78 } | 108 } |
79 | 109 |
| 110 void SetUpAutoMountContext(base::FilePath* mnt_point) { |
| 111 *mnt_point = temp_dir_.path().AppendASCII("auto_mount_dir"); |
| 112 ASSERT_TRUE(base::CreateDirectory(*mnt_point)); |
| 113 |
| 114 ScopedVector<fileapi::FileSystemBackend> additional_providers; |
| 115 additional_providers.push_back(new TestFileSystemBackend( |
| 116 base::MessageLoopProxy::current().get(), *mnt_point)); |
| 117 |
| 118 std::vector<fileapi::URLRequestAutoMountHandler> handlers; |
| 119 handlers.push_back(base::Bind(&TestAutoMountForURLRequest)); |
| 120 |
| 121 file_system_context_ = CreateFileSystemContextWithAutoMountersForTesting( |
| 122 NULL, additional_providers.Pass(), handlers, temp_dir_.path()); |
| 123 } |
| 124 |
80 void OnOpenFileSystem(const GURL& root_url, | 125 void OnOpenFileSystem(const GURL& root_url, |
81 const std::string& name, | 126 const std::string& name, |
82 base::File::Error result) { | 127 base::File::Error result) { |
83 ASSERT_EQ(base::File::FILE_OK, result); | 128 ASSERT_EQ(base::File::FILE_OK, result); |
84 } | 129 } |
85 | 130 |
86 void TestRequestHelper(const GURL& url, bool run_to_completion, | 131 void TestRequestHelper(const GURL& url, bool run_to_completion, |
87 FileSystemContext* file_system_context) { | 132 FileSystemContext* file_system_context) { |
88 delegate_.reset(new net::TestDelegate()); | 133 delegate_.reset(new net::TestDelegate()); |
89 delegate_->set_quit_on_redirect(true); | 134 delegate_->set_quit_on_redirect(true); |
90 request_ = empty_context_.CreateRequest( | 135 request_ = empty_context_.CreateRequest( |
91 url, net::DEFAULT_PRIORITY, delegate_.get(), NULL); | 136 url, net::DEFAULT_PRIORITY, delegate_.get(), NULL); |
92 job_ = new fileapi::FileSystemDirURLRequestJob( | 137 job_ = new fileapi::FileSystemDirURLRequestJob( |
93 request_.get(), NULL, file_system_context); | 138 request_.get(), NULL, url.GetOrigin().host(), file_system_context); |
94 | 139 |
95 request_->Start(); | 140 request_->Start(); |
96 ASSERT_TRUE(request_->is_pending()); // verify that we're starting async | 141 ASSERT_TRUE(request_->is_pending()); // verify that we're starting async |
97 if (run_to_completion) | 142 if (run_to_completion) |
98 base::MessageLoop::current()->Run(); | 143 base::MessageLoop::current()->Run(); |
99 } | 144 } |
100 | 145 |
101 void TestRequest(const GURL& url) { | 146 void TestRequest(const GURL& url) { |
102 TestRequestHelper(url, true, file_system_context_.get()); | 147 TestRequestHelper(url, true, file_system_context_.get()); |
103 } | 148 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 | 196 |
152 base::File::Error GetFileInfo(const base::FilePath& path, | 197 base::File::Error GetFileInfo(const base::FilePath& path, |
153 base::File::Info* file_info, | 198 base::File::Info* file_info, |
154 base::FilePath* platform_file_path) { | 199 base::FilePath* platform_file_path) { |
155 scoped_ptr<FileSystemOperationContext> context(NewOperationContext()); | 200 scoped_ptr<FileSystemOperationContext> context(NewOperationContext()); |
156 return file_util()->GetFileInfo(context.get(), | 201 return file_util()->GetFileInfo(context.get(), |
157 CreateURL(path), | 202 CreateURL(path), |
158 file_info, platform_file_path); | 203 file_info, platform_file_path); |
159 } | 204 } |
160 | 205 |
| 206 // If |size| is negative, the reported size is ignored. |
161 void VerifyListingEntry(const std::string& entry_line, | 207 void VerifyListingEntry(const std::string& entry_line, |
162 const std::string& name, | 208 const std::string& name, |
163 const std::string& url, | 209 const std::string& url, |
164 bool is_directory, | 210 bool is_directory, |
165 int64 size) { | 211 int64 size) { |
166 #define STR "([^\"]*)" | 212 #define STR "([^\"]*)" |
167 icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR | 213 icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR |
168 "\",(0|1),\"" STR "\",\"" STR "\"\\);</script>"); | 214 "\",(0|1),\"" STR "\",\"" STR "\"\\);</script>"); |
169 #undef STR | 215 #undef STR |
170 icu::UnicodeString input(entry_line.c_str()); | 216 icu::UnicodeString input(entry_line.c_str()); |
171 | 217 |
172 UErrorCode status = U_ZERO_ERROR; | 218 UErrorCode status = U_ZERO_ERROR; |
173 icu::RegexMatcher match(pattern, input, 0, status); | 219 icu::RegexMatcher match(pattern, input, 0, status); |
174 | 220 |
175 EXPECT_TRUE(match.find()); | 221 EXPECT_TRUE(match.find()); |
176 EXPECT_EQ(5, match.groupCount()); | 222 EXPECT_EQ(5, match.groupCount()); |
177 EXPECT_EQ(icu::UnicodeString(name.c_str()), match.group(1, status)); | 223 EXPECT_EQ(icu::UnicodeString(name.c_str()), match.group(1, status)); |
178 EXPECT_EQ(icu::UnicodeString(url.c_str()), match.group(2, status)); | 224 EXPECT_EQ(icu::UnicodeString(url.c_str()), match.group(2, status)); |
179 EXPECT_EQ(icu::UnicodeString(is_directory ? "1" : "0"), | 225 EXPECT_EQ(icu::UnicodeString(is_directory ? "1" : "0"), |
180 match.group(3, status)); | 226 match.group(3, status)); |
181 icu::UnicodeString size_string(FormatBytesUnlocalized(size).c_str()); | 227 if (size >= 0) { |
182 EXPECT_EQ(size_string, match.group(4, status)); | 228 icu::UnicodeString size_string(FormatBytesUnlocalized(size).c_str()); |
| 229 EXPECT_EQ(size_string, match.group(4, status)); |
| 230 } |
183 | 231 |
184 base::Time date; | 232 base::Time date; |
185 icu::UnicodeString date_ustr(match.group(5, status)); | 233 icu::UnicodeString date_ustr(match.group(5, status)); |
186 std::string date_str; | 234 std::string date_str; |
187 base::UTF16ToUTF8(date_ustr.getBuffer(), date_ustr.length(), &date_str); | 235 base::UTF16ToUTF8(date_ustr.getBuffer(), date_ustr.length(), &date_str); |
188 EXPECT_TRUE(base::Time::FromString(date_str.c_str(), &date)); | 236 EXPECT_TRUE(base::Time::FromString(date_str.c_str(), &date)); |
189 EXPECT_FALSE(date.is_null()); | 237 EXPECT_FALSE(date.is_null()); |
190 } | 238 } |
191 | 239 |
192 GURL CreateFileSystemURL(const std::string path) { | 240 GURL CreateFileSystemURL(const std::string path) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 EXPECT_EQ("<script>start(\"foo\\\\bar\");</script>", line); | 306 EXPECT_EQ("<script>start(\"foo\\\\bar\");</script>", line); |
259 #elif defined(OS_POSIX) | 307 #elif defined(OS_POSIX) |
260 EXPECT_EQ("<script>start(\"/foo/bar\");</script>", line); | 308 EXPECT_EQ("<script>start(\"/foo/bar\");</script>", line); |
261 #endif | 309 #endif |
262 | 310 |
263 EXPECT_TRUE(!!std::getline(in, line)); | 311 EXPECT_TRUE(!!std::getline(in, line)); |
264 VerifyListingEntry(line, "hoge", "hoge", false, 10); | 312 VerifyListingEntry(line, "hoge", "hoge", false, 10); |
265 | 313 |
266 EXPECT_TRUE(!!std::getline(in, line)); | 314 EXPECT_TRUE(!!std::getline(in, line)); |
267 VerifyListingEntry(line, "baz", "baz", true, 0); | 315 VerifyListingEntry(line, "baz", "baz", true, 0); |
| 316 EXPECT_FALSE(!!std::getline(in, line)); |
268 } | 317 } |
269 | 318 |
270 TEST_F(FileSystemDirURLRequestJobTest, InvalidURL) { | 319 TEST_F(FileSystemDirURLRequestJobTest, InvalidURL) { |
271 TestRequest(GURL("filesystem:/foo/bar/baz")); | 320 TestRequest(GURL("filesystem:/foo/bar/baz")); |
272 ASSERT_FALSE(request_->is_pending()); | 321 ASSERT_FALSE(request_->is_pending()); |
273 EXPECT_TRUE(delegate_->request_failed()); | 322 EXPECT_TRUE(delegate_->request_failed()); |
274 ASSERT_FALSE(request_->status().is_success()); | 323 ASSERT_FALSE(request_->status().is_success()); |
275 EXPECT_EQ(net::ERR_INVALID_URL, request_->status().error()); | 324 EXPECT_EQ(net::ERR_INVALID_URL, request_->status().error()); |
276 } | 325 } |
277 | 326 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 EXPECT_TRUE(!!std::getline(in, line)); | 363 EXPECT_TRUE(!!std::getline(in, line)); |
315 EXPECT_FALSE(!!std::getline(in, line)); | 364 EXPECT_FALSE(!!std::getline(in, line)); |
316 | 365 |
317 TestRequestWithContext(CreateFileSystemURL("foo"), | 366 TestRequestWithContext(CreateFileSystemURL("foo"), |
318 file_system_context.get()); | 367 file_system_context.get()); |
319 ASSERT_FALSE(request_->is_pending()); | 368 ASSERT_FALSE(request_->is_pending()); |
320 ASSERT_FALSE(request_->status().is_success()); | 369 ASSERT_FALSE(request_->status().is_success()); |
321 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); | 370 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); |
322 } | 371 } |
323 | 372 |
| 373 TEST_F(FileSystemDirURLRequestJobTest, AutoMountDirectoryListing) { |
| 374 base::FilePath mnt_point; |
| 375 SetUpAutoMountContext(&mnt_point); |
| 376 ASSERT_TRUE(base::CreateDirectory(mnt_point)); |
| 377 ASSERT_TRUE(base::CreateDirectory(mnt_point.AppendASCII("foo"))); |
| 378 ASSERT_EQ(10, |
| 379 base::WriteFile(mnt_point.AppendASCII("bar"), "1234567890", 10)); |
| 380 |
| 381 TestRequest(GURL("filesystem:http://automount/external/mnt_name")); |
| 382 |
| 383 ASSERT_FALSE(request_->is_pending()); |
| 384 EXPECT_EQ(1, delegate_->response_started_count()); |
| 385 EXPECT_FALSE(delegate_->received_data_before_response()); |
| 386 EXPECT_GT(delegate_->bytes_received(), 0); |
| 387 |
| 388 std::istringstream in(delegate_->data_received()); |
| 389 std::string line; |
| 390 EXPECT_TRUE(!!std::getline(in, line)); // |line| contains the temp dir path. |
| 391 |
| 392 // Result order is not guaranteed, so sort the results. |
| 393 std::vector<std::string> listing_entries; |
| 394 while (!!std::getline(in, line)) |
| 395 listing_entries.push_back(line); |
| 396 |
| 397 ASSERT_EQ(2U, listing_entries.size()); |
| 398 std::sort(listing_entries.begin(), listing_entries.end()); |
| 399 VerifyListingEntry(listing_entries[0], "bar", "bar", false, 10); |
| 400 VerifyListingEntry(listing_entries[1], "foo", "foo", true, -1); |
| 401 |
| 402 ASSERT_TRUE( |
| 403 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( |
| 404 kValidExternalMountPoint)); |
| 405 } |
| 406 |
| 407 TEST_F(FileSystemDirURLRequestJobTest, AutoMountInvalidRoot) { |
| 408 base::FilePath mnt_point; |
| 409 SetUpAutoMountContext(&mnt_point); |
| 410 TestRequest(GURL("filesystem:http://automount/external/invalid")); |
| 411 |
| 412 ASSERT_FALSE(request_->is_pending()); |
| 413 ASSERT_FALSE(request_->status().is_success()); |
| 414 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); |
| 415 |
| 416 ASSERT_FALSE( |
| 417 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( |
| 418 "invalid")); |
| 419 } |
| 420 |
| 421 TEST_F(FileSystemDirURLRequestJobTest, AutoMountNoHandler) { |
| 422 base::FilePath mnt_point; |
| 423 SetUpAutoMountContext(&mnt_point); |
| 424 TestRequest(GURL("filesystem:http://noauto/external/mnt_name")); |
| 425 |
| 426 ASSERT_FALSE(request_->is_pending()); |
| 427 ASSERT_FALSE(request_->status().is_success()); |
| 428 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); |
| 429 |
| 430 ASSERT_FALSE( |
| 431 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( |
| 432 kValidExternalMountPoint)); |
| 433 } |
| 434 |
324 } // namespace (anonymous) | 435 } // namespace (anonymous) |
325 } // namespace content | 436 } // namespace content |
OLD | NEW |