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" | |
10 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
11 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
12 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
13 #include "base/memory/scoped_vector.h" | |
14 #include "base/memory/weak_ptr.h" | 12 #include "base/memory/weak_ptr.h" |
15 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
16 #include "base/platform_file.h" | 14 #include "base/platform_file.h" |
17 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
18 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
19 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
20 #include "content/public/test/test_file_system_backend.h" | |
21 #include "content/public/test/test_file_system_context.h" | 18 #include "content/public/test/test_file_system_context.h" |
22 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
23 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
24 #include "net/base/request_priority.h" | 21 #include "net/base/request_priority.h" |
25 #include "net/http/http_request_headers.h" | 22 #include "net/http/http_request_headers.h" |
26 #include "net/url_request/url_request.h" | 23 #include "net/url_request/url_request.h" |
27 #include "net/url_request/url_request_context.h" | 24 #include "net/url_request/url_request_context.h" |
28 #include "net/url_request/url_request_test_util.h" | 25 #include "net/url_request/url_request_test_util.h" |
29 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
30 #include "third_party/icu/source/i18n/unicode/regex.h" | 27 #include "third_party/icu/source/i18n/unicode/regex.h" |
31 #include "webkit/browser/fileapi/external_mount_points.h" | |
32 #include "webkit/browser/fileapi/file_system_context.h" | 28 #include "webkit/browser/fileapi/file_system_context.h" |
33 #include "webkit/browser/fileapi/file_system_file_util.h" | 29 #include "webkit/browser/fileapi/file_system_file_util.h" |
34 #include "webkit/browser/fileapi/file_system_operation_context.h" | 30 #include "webkit/browser/fileapi/file_system_operation_context.h" |
35 #include "webkit/browser/fileapi/file_system_url.h" | 31 #include "webkit/browser/fileapi/file_system_url.h" |
36 #include "webkit/browser/quota/mock_special_storage_policy.h" | 32 #include "webkit/browser/quota/mock_special_storage_policy.h" |
37 | 33 |
38 using fileapi::FileSystemContext; | 34 using fileapi::FileSystemContext; |
39 using fileapi::FileSystemOperationContext; | 35 using fileapi::FileSystemOperationContext; |
40 using fileapi::FileSystemURL; | 36 using fileapi::FileSystemURL; |
41 | 37 |
42 namespace content { | 38 namespace content { |
43 namespace { | 39 namespace { |
44 | 40 |
45 // We always use the TEMPORARY FileSystem in this test. | 41 // We always use the TEMPORARY FileSystem in this test. |
46 const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/"; | 42 static const char kFileSystemURLPrefix[] = |
47 | 43 "filesystem:http://remote/temporary/"; |
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 } | |
74 | 44 |
75 } // namespace | 45 } // namespace |
76 | 46 |
77 class FileSystemDirURLRequestJobTest : public testing::Test { | 47 class FileSystemDirURLRequestJobTest : public testing::Test { |
78 protected: | 48 protected: |
79 FileSystemDirURLRequestJobTest() | 49 FileSystemDirURLRequestJobTest() |
80 : weak_factory_(this) { | 50 : weak_factory_(this) { |
81 } | 51 } |
82 | 52 |
83 virtual void SetUp() OVERRIDE { | 53 virtual void SetUp() OVERRIDE { |
(...skipping 16 matching lines...) Expand all Loading... |
100 | 70 |
101 virtual void TearDown() OVERRIDE { | 71 virtual void TearDown() OVERRIDE { |
102 // NOTE: order matters, request must die before delegate | 72 // NOTE: order matters, request must die before delegate |
103 request_.reset(NULL); | 73 request_.reset(NULL); |
104 delegate_.reset(NULL); | 74 delegate_.reset(NULL); |
105 | 75 |
106 net::URLRequest::Deprecated::RegisterProtocolFactory("filesystem", NULL); | 76 net::URLRequest::Deprecated::RegisterProtocolFactory("filesystem", NULL); |
107 ClearUnusedJob(); | 77 ClearUnusedJob(); |
108 } | 78 } |
109 | 79 |
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 | |
125 void OnOpenFileSystem(const GURL& root_url, | 80 void OnOpenFileSystem(const GURL& root_url, |
126 const std::string& name, | 81 const std::string& name, |
127 base::File::Error result) { | 82 base::File::Error result) { |
128 ASSERT_EQ(base::File::FILE_OK, result); | 83 ASSERT_EQ(base::File::FILE_OK, result); |
129 } | 84 } |
130 | 85 |
131 void TestRequestHelper(const GURL& url, bool run_to_completion, | 86 void TestRequestHelper(const GURL& url, bool run_to_completion, |
132 FileSystemContext* file_system_context) { | 87 FileSystemContext* file_system_context) { |
133 delegate_.reset(new net::TestDelegate()); | 88 delegate_.reset(new net::TestDelegate()); |
134 delegate_->set_quit_on_redirect(true); | 89 delegate_->set_quit_on_redirect(true); |
135 request_ = empty_context_.CreateRequest( | 90 request_ = empty_context_.CreateRequest( |
136 url, net::DEFAULT_PRIORITY, delegate_.get(), NULL); | 91 url, net::DEFAULT_PRIORITY, delegate_.get(), NULL); |
137 job_ = new fileapi::FileSystemDirURLRequestJob( | 92 job_ = new fileapi::FileSystemDirURLRequestJob( |
138 request_.get(), NULL, url.GetOrigin().host(), file_system_context); | 93 request_.get(), NULL, file_system_context); |
139 | 94 |
140 request_->Start(); | 95 request_->Start(); |
141 ASSERT_TRUE(request_->is_pending()); // verify that we're starting async | 96 ASSERT_TRUE(request_->is_pending()); // verify that we're starting async |
142 if (run_to_completion) | 97 if (run_to_completion) |
143 base::MessageLoop::current()->Run(); | 98 base::MessageLoop::current()->Run(); |
144 } | 99 } |
145 | 100 |
146 void TestRequest(const GURL& url) { | 101 void TestRequest(const GURL& url) { |
147 TestRequestHelper(url, true, file_system_context_.get()); | 102 TestRequestHelper(url, true, file_system_context_.get()); |
148 } | 103 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 | 151 |
197 base::File::Error GetFileInfo(const base::FilePath& path, | 152 base::File::Error GetFileInfo(const base::FilePath& path, |
198 base::File::Info* file_info, | 153 base::File::Info* file_info, |
199 base::FilePath* platform_file_path) { | 154 base::FilePath* platform_file_path) { |
200 scoped_ptr<FileSystemOperationContext> context(NewOperationContext()); | 155 scoped_ptr<FileSystemOperationContext> context(NewOperationContext()); |
201 return file_util()->GetFileInfo(context.get(), | 156 return file_util()->GetFileInfo(context.get(), |
202 CreateURL(path), | 157 CreateURL(path), |
203 file_info, platform_file_path); | 158 file_info, platform_file_path); |
204 } | 159 } |
205 | 160 |
206 // If |size| is negative, the reported size is ignored. | |
207 void VerifyListingEntry(const std::string& entry_line, | 161 void VerifyListingEntry(const std::string& entry_line, |
208 const std::string& name, | 162 const std::string& name, |
209 const std::string& url, | 163 const std::string& url, |
210 bool is_directory, | 164 bool is_directory, |
211 int64 size) { | 165 int64 size) { |
212 #define STR "([^\"]*)" | 166 #define STR "([^\"]*)" |
213 icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR | 167 icu::UnicodeString pattern("^<script>addRow\\(\"" STR "\",\"" STR |
214 "\",(0|1),\"" STR "\",\"" STR "\"\\);</script>"); | 168 "\",(0|1),\"" STR "\",\"" STR "\"\\);</script>"); |
215 #undef STR | 169 #undef STR |
216 icu::UnicodeString input(entry_line.c_str()); | 170 icu::UnicodeString input(entry_line.c_str()); |
217 | 171 |
218 UErrorCode status = U_ZERO_ERROR; | 172 UErrorCode status = U_ZERO_ERROR; |
219 icu::RegexMatcher match(pattern, input, 0, status); | 173 icu::RegexMatcher match(pattern, input, 0, status); |
220 | 174 |
221 EXPECT_TRUE(match.find()); | 175 EXPECT_TRUE(match.find()); |
222 EXPECT_EQ(5, match.groupCount()); | 176 EXPECT_EQ(5, match.groupCount()); |
223 EXPECT_EQ(icu::UnicodeString(name.c_str()), match.group(1, status)); | 177 EXPECT_EQ(icu::UnicodeString(name.c_str()), match.group(1, status)); |
224 EXPECT_EQ(icu::UnicodeString(url.c_str()), match.group(2, status)); | 178 EXPECT_EQ(icu::UnicodeString(url.c_str()), match.group(2, status)); |
225 EXPECT_EQ(icu::UnicodeString(is_directory ? "1" : "0"), | 179 EXPECT_EQ(icu::UnicodeString(is_directory ? "1" : "0"), |
226 match.group(3, status)); | 180 match.group(3, status)); |
227 if (size >= 0) { | 181 icu::UnicodeString size_string(FormatBytesUnlocalized(size).c_str()); |
228 icu::UnicodeString size_string(FormatBytesUnlocalized(size).c_str()); | 182 EXPECT_EQ(size_string, match.group(4, status)); |
229 EXPECT_EQ(size_string, match.group(4, status)); | |
230 } | |
231 | 183 |
232 base::Time date; | 184 base::Time date; |
233 icu::UnicodeString date_ustr(match.group(5, status)); | 185 icu::UnicodeString date_ustr(match.group(5, status)); |
234 std::string date_str; | 186 std::string date_str; |
235 base::UTF16ToUTF8(date_ustr.getBuffer(), date_ustr.length(), &date_str); | 187 base::UTF16ToUTF8(date_ustr.getBuffer(), date_ustr.length(), &date_str); |
236 EXPECT_TRUE(base::Time::FromString(date_str.c_str(), &date)); | 188 EXPECT_TRUE(base::Time::FromString(date_str.c_str(), &date)); |
237 EXPECT_FALSE(date.is_null()); | 189 EXPECT_FALSE(date.is_null()); |
238 } | 190 } |
239 | 191 |
240 GURL CreateFileSystemURL(const std::string path) { | 192 GURL CreateFileSystemURL(const std::string path) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 EXPECT_EQ("<script>start(\"foo\\\\bar\");</script>", line); | 258 EXPECT_EQ("<script>start(\"foo\\\\bar\");</script>", line); |
307 #elif defined(OS_POSIX) | 259 #elif defined(OS_POSIX) |
308 EXPECT_EQ("<script>start(\"/foo/bar\");</script>", line); | 260 EXPECT_EQ("<script>start(\"/foo/bar\");</script>", line); |
309 #endif | 261 #endif |
310 | 262 |
311 EXPECT_TRUE(!!std::getline(in, line)); | 263 EXPECT_TRUE(!!std::getline(in, line)); |
312 VerifyListingEntry(line, "hoge", "hoge", false, 10); | 264 VerifyListingEntry(line, "hoge", "hoge", false, 10); |
313 | 265 |
314 EXPECT_TRUE(!!std::getline(in, line)); | 266 EXPECT_TRUE(!!std::getline(in, line)); |
315 VerifyListingEntry(line, "baz", "baz", true, 0); | 267 VerifyListingEntry(line, "baz", "baz", true, 0); |
316 EXPECT_FALSE(!!std::getline(in, line)); | |
317 } | 268 } |
318 | 269 |
319 TEST_F(FileSystemDirURLRequestJobTest, InvalidURL) { | 270 TEST_F(FileSystemDirURLRequestJobTest, InvalidURL) { |
320 TestRequest(GURL("filesystem:/foo/bar/baz")); | 271 TestRequest(GURL("filesystem:/foo/bar/baz")); |
321 ASSERT_FALSE(request_->is_pending()); | 272 ASSERT_FALSE(request_->is_pending()); |
322 EXPECT_TRUE(delegate_->request_failed()); | 273 EXPECT_TRUE(delegate_->request_failed()); |
323 ASSERT_FALSE(request_->status().is_success()); | 274 ASSERT_FALSE(request_->status().is_success()); |
324 EXPECT_EQ(net::ERR_INVALID_URL, request_->status().error()); | 275 EXPECT_EQ(net::ERR_INVALID_URL, request_->status().error()); |
325 } | 276 } |
326 | 277 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 EXPECT_TRUE(!!std::getline(in, line)); | 314 EXPECT_TRUE(!!std::getline(in, line)); |
364 EXPECT_FALSE(!!std::getline(in, line)); | 315 EXPECT_FALSE(!!std::getline(in, line)); |
365 | 316 |
366 TestRequestWithContext(CreateFileSystemURL("foo"), | 317 TestRequestWithContext(CreateFileSystemURL("foo"), |
367 file_system_context.get()); | 318 file_system_context.get()); |
368 ASSERT_FALSE(request_->is_pending()); | 319 ASSERT_FALSE(request_->is_pending()); |
369 ASSERT_FALSE(request_->status().is_success()); | 320 ASSERT_FALSE(request_->status().is_success()); |
370 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); | 321 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error()); |
371 } | 322 } |
372 | 323 |
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 | |
435 } // namespace (anonymous) | 324 } // namespace (anonymous) |
436 } // namespace content | 325 } // namespace content |
OLD | NEW |