OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/fileapi/external_file_url_request_job.h" | 5 #include "chrome/browser/chromeos/fileapi/external_file_url_request_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/chromeos/drive/file_system_util.h" | 14 #include "chrome/browser/chromeos/drive/file_system_util.h" |
15 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" | 15 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" |
16 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" | 16 #include "chrome/browser/extensions/api/file_handlers/mime_util.h" |
17 #include "chrome/browser/profiles/profile_manager.h" | 17 #include "chrome/browser/profiles/profile_manager.h" |
18 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/storage_partition.h" | 20 #include "content/public/browser/storage_partition.h" |
21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
22 #include "net/http/http_byte_range.h" | 22 #include "net/http/http_byte_range.h" |
23 #include "net/http/http_request_headers.h" | 23 #include "net/http/http_request_headers.h" |
24 #include "net/http/http_response_info.h" | 24 #include "net/http/http_response_info.h" |
25 #include "net/http/http_util.h" | 25 #include "net/http/http_util.h" |
26 #include "net/url_request/url_request.h" | 26 #include "net/url_request/url_request.h" |
27 #include "net/url_request/url_request_status.h" | 27 #include "net/url_request/url_request_status.h" |
28 #include "storage/browser/fileapi/external_mount_points.h" | |
28 #include "storage/browser/fileapi/file_system_backend.h" | 29 #include "storage/browser/fileapi/file_system_backend.h" |
29 #include "storage/browser/fileapi/file_system_context.h" | 30 #include "storage/browser/fileapi/file_system_context.h" |
30 #include "storage/browser/fileapi/file_system_operation_runner.h" | 31 #include "storage/browser/fileapi/file_system_operation_runner.h" |
32 #include "storage/browser/fileapi/isolated_context.h" | |
31 | 33 |
32 using content::BrowserThread; | 34 using content::BrowserThread; |
33 | 35 |
34 namespace chromeos { | 36 namespace chromeos { |
35 namespace { | 37 namespace { |
36 | 38 |
37 const char kMimeTypeForRFC822[] = "message/rfc822"; | 39 const char kMimeTypeForRFC822[] = "message/rfc822"; |
38 const char kMimeTypeForMHTML[] = "multipart/related"; | 40 const char kMimeTypeForMHTML[] = "multipart/related"; |
39 | 41 |
42 storage::FileSystemURL CreateIsolatedURLFromVirtualPath( | |
43 const storage::FileSystemContext& context, | |
44 const base::FilePath& virtual_path) { | |
45 std::string file_system_id; | |
46 storage::FileSystemType file_system_type; | |
47 base::FilePath path; | |
48 { | |
49 std::string cracked_id; | |
50 storage::FileSystemMountOption option; | |
51 storage::ExternalMountPoints::GetSystemInstance()->CrackVirtualPath( | |
52 virtual_path, | |
53 &file_system_id, | |
54 &file_system_type, | |
55 &cracked_id, | |
56 &path, | |
57 &option); | |
58 } | |
59 if (!IsExternalFileURLType(file_system_type)) | |
60 return storage::FileSystemURL(); | |
61 std::string register_name; | |
62 const std::string isolated_file_system_id = | |
63 storage::IsolatedContext::GetInstance()->RegisterFileSystemForPath( | |
64 file_system_type, file_system_id, path, ®ister_name); | |
65 storage::FileSystemURL file_system_url = context.CreateCrackedFileSystemURL( | |
66 GURL(""), | |
mtomasz
2014/09/29 12:47:40
nit: Maybe just GURL()?
hirono
2014/09/29 13:24:02
Done.
| |
67 storage::kFileSystemTypeIsolated, | |
68 base::FilePath(isolated_file_system_id).Append(register_name)); | |
69 DCHECK(file_system_url.is_valid()); | |
70 return file_system_url; | |
71 } | |
72 | |
40 // Helper for obtaining FileSystemContext, FileSystemURL, and mime type on the | 73 // Helper for obtaining FileSystemContext, FileSystemURL, and mime type on the |
41 // UI thread. | 74 // UI thread. |
42 class URLHelper { | 75 class URLHelper { |
43 public: | 76 public: |
44 // The scoped pointer to control lifetime of the instance itself. The pointer | 77 // The scoped pointer to control lifetime of the instance itself. The pointer |
45 // is passed to callback functions and binds the lifetime of the instance to | 78 // is passed to callback functions and binds the lifetime of the instance to |
46 // the callback's lifetime. | 79 // the callback's lifetime. |
47 typedef scoped_ptr<URLHelper> Lifetime; | 80 typedef scoped_ptr<URLHelper> Lifetime; |
48 | 81 |
49 URLHelper(void* profile_id, | 82 URLHelper(void* profile_id, |
(...skipping 22 matching lines...) Expand all Loading... | |
72 DCHECK(storage); | 105 DCHECK(storage); |
73 | 106 |
74 scoped_refptr<storage::FileSystemContext> context = | 107 scoped_refptr<storage::FileSystemContext> context = |
75 storage->GetFileSystemContext(); | 108 storage->GetFileSystemContext(); |
76 DCHECK(context.get()); | 109 DCHECK(context.get()); |
77 | 110 |
78 // Obtain the absolute path in the file system. | 111 // Obtain the absolute path in the file system. |
79 const base::FilePath virtual_path = ExternalFileURLToVirtualPath(url_); | 112 const base::FilePath virtual_path = ExternalFileURLToVirtualPath(url_); |
80 | 113 |
81 // Obtain the file system URL. | 114 // Obtain the file system URL. |
82 // TODO(hirono): After removing MHTML support, stop to use the special | 115 file_system_url_ = CreateIsolatedURLFromVirtualPath(*context, virtual_path); |
83 // drive: scheme and use filesystem: URL directly. crbug.com/415455 | |
84 file_system_url_ = context->CreateCrackedFileSystemURL( | |
85 GURL(std::string(chrome::kExternalFileScheme) + ":"), | |
86 storage::kFileSystemTypeExternal, | |
87 virtual_path); | |
88 | 116 |
89 // Check if the obtained path providing external file URL or not. | 117 // Check if the obtained path providing external file URL or not. |
90 if (FileSystemURLToExternalFileURL(file_system_url_).is_empty()) { | 118 if (!file_system_url_.is_valid()) { |
91 ReplyResult(net::ERR_INVALID_URL); | 119 ReplyResult(net::ERR_INVALID_URL); |
92 return; | 120 return; |
93 } | 121 } |
94 | 122 |
123 isolated_file_system_scope_.reset( | |
124 new ExternalFileURLRequestJob::IsolatedFileSystemScope( | |
125 file_system_url_.filesystem_id())); | |
95 file_system_context_ = context; | 126 file_system_context_ = context; |
96 | 127 |
97 extensions::app_file_handler_util::GetMimeTypeForLocalPath( | 128 extensions::app_file_handler_util::GetMimeTypeForLocalPath( |
98 profile, | 129 profile, |
99 file_system_url_.path(), | 130 file_system_url_.path(), |
100 base::Bind(&URLHelper::OnGotMimeTypeOnUIThread, | 131 base::Bind(&URLHelper::OnGotMimeTypeOnUIThread, |
101 base::Unretained(this), | 132 base::Unretained(this), |
102 base::Passed(&lifetime))); | 133 base::Passed(&lifetime))); |
103 } | 134 } |
104 | 135 |
105 void OnGotMimeTypeOnUIThread(Lifetime lifetime, | 136 void OnGotMimeTypeOnUIThread(Lifetime lifetime, |
106 const std::string& mime_type) { | 137 const std::string& mime_type) { |
107 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 138 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
108 mime_type_ = mime_type; | 139 mime_type_ = mime_type; |
109 | 140 |
110 if (mime_type_ == kMimeTypeForRFC822) | 141 if (mime_type_ == kMimeTypeForRFC822) |
111 mime_type_ = kMimeTypeForMHTML; | 142 mime_type_ = kMimeTypeForMHTML; |
112 | 143 |
113 ReplyResult(net::OK); | 144 ReplyResult(net::OK); |
114 } | 145 } |
115 | 146 |
116 void ReplyResult(net::Error error) { | 147 void ReplyResult(net::Error error) { |
117 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 148 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
118 | 149 |
119 BrowserThread::PostTask(BrowserThread::IO, | 150 BrowserThread::PostTask( |
120 FROM_HERE, | 151 BrowserThread::IO, |
121 base::Bind(callback_, | 152 FROM_HERE, |
122 error, | 153 base::Bind(callback_, |
123 file_system_context_, | 154 error, |
124 file_system_url_, | 155 file_system_context_, |
125 mime_type_)); | 156 base::Passed(&isolated_file_system_scope_), |
157 file_system_url_, | |
158 mime_type_)); | |
126 } | 159 } |
127 | 160 |
128 void* const profile_id_; | 161 void* const profile_id_; |
129 const GURL url_; | 162 const GURL url_; |
130 const ExternalFileURLRequestJob::HelperCallback callback_; | 163 const ExternalFileURLRequestJob::HelperCallback callback_; |
131 scoped_refptr<storage::FileSystemContext> file_system_context_; | 164 scoped_refptr<storage::FileSystemContext> file_system_context_; |
165 scoped_ptr<ExternalFileURLRequestJob::IsolatedFileSystemScope> | |
166 isolated_file_system_scope_; | |
132 storage::FileSystemURL file_system_url_; | 167 storage::FileSystemURL file_system_url_; |
133 std::string mime_type_; | 168 std::string mime_type_; |
134 | 169 |
135 DISALLOW_COPY_AND_ASSIGN(URLHelper); | 170 DISALLOW_COPY_AND_ASSIGN(URLHelper); |
136 }; | 171 }; |
137 | 172 |
138 } // namespace | 173 } // namespace |
139 | 174 |
175 ExternalFileURLRequestJob::IsolatedFileSystemScope::IsolatedFileSystemScope( | |
176 const std::string& file_system_id) | |
177 : file_system_id_(file_system_id) { | |
178 } | |
179 | |
180 ExternalFileURLRequestJob::IsolatedFileSystemScope::~IsolatedFileSystemScope() { | |
181 storage::IsolatedContext::GetInstance()->RevokeFileSystem(file_system_id_); | |
182 } | |
183 | |
140 ExternalFileURLRequestJob::ExternalFileURLRequestJob( | 184 ExternalFileURLRequestJob::ExternalFileURLRequestJob( |
141 void* profile_id, | 185 void* profile_id, |
142 net::URLRequest* request, | 186 net::URLRequest* request, |
143 net::NetworkDelegate* network_delegate) | 187 net::NetworkDelegate* network_delegate) |
144 : net::URLRequestJob(request, network_delegate), | 188 : net::URLRequestJob(request, network_delegate), |
145 profile_id_(profile_id), | 189 profile_id_(profile_id), |
146 remaining_bytes_(0), | 190 remaining_bytes_(0), |
147 weak_ptr_factory_(this) { | 191 weak_ptr_factory_(this) { |
148 } | 192 } |
149 | 193 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 // Owned by itself. | 232 // Owned by itself. |
189 new URLHelper(profile_id_, | 233 new URLHelper(profile_id_, |
190 request()->url(), | 234 request()->url(), |
191 base::Bind(&ExternalFileURLRequestJob::OnHelperResultObtained, | 235 base::Bind(&ExternalFileURLRequestJob::OnHelperResultObtained, |
192 weak_ptr_factory_.GetWeakPtr())); | 236 weak_ptr_factory_.GetWeakPtr())); |
193 } | 237 } |
194 | 238 |
195 void ExternalFileURLRequestJob::OnHelperResultObtained( | 239 void ExternalFileURLRequestJob::OnHelperResultObtained( |
196 net::Error error, | 240 net::Error error, |
197 const scoped_refptr<storage::FileSystemContext>& file_system_context, | 241 const scoped_refptr<storage::FileSystemContext>& file_system_context, |
242 scoped_ptr<IsolatedFileSystemScope> isolated_file_system_scope, | |
198 const storage::FileSystemURL& file_system_url, | 243 const storage::FileSystemURL& file_system_url, |
199 const std::string& mime_type) { | 244 const std::string& mime_type) { |
200 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
201 | 246 |
202 if (error != net::OK) { | 247 if (error != net::OK) { |
203 NotifyStartError( | 248 NotifyStartError( |
204 net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); | 249 net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); |
205 return; | 250 return; |
206 } | 251 } |
207 | 252 |
208 DCHECK(file_system_context.get()); | 253 DCHECK(file_system_context.get()); |
209 file_system_context_ = file_system_context; | 254 file_system_context_ = file_system_context; |
255 isolated_file_system_scope_ = isolated_file_system_scope.Pass(); | |
210 file_system_url_ = file_system_url; | 256 file_system_url_ = file_system_url; |
211 mime_type_ = mime_type; | 257 mime_type_ = mime_type; |
212 | 258 |
213 // Check if the entry has a redirect URL. | 259 // Check if the entry has a redirect URL. |
214 file_system_context_->external_backend()->GetRedirectURLForContents( | 260 file_system_context_->external_backend()->GetRedirectURLForContents( |
215 file_system_url_, | 261 file_system_url_, |
216 base::Bind(&ExternalFileURLRequestJob::OnRedirectURLObtained, | 262 base::Bind(&ExternalFileURLRequestJob::OnRedirectURLObtained, |
217 weak_ptr_factory_.GetWeakPtr())); | 263 weak_ptr_factory_.GetWeakPtr())); |
218 } | 264 } |
219 | 265 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 return; | 304 return; |
259 } | 305 } |
260 const int64 offset = byte_range_.first_byte_position(); | 306 const int64 offset = byte_range_.first_byte_position(); |
261 const int64 size = | 307 const int64 size = |
262 byte_range_.last_byte_position() + 1 - byte_range_.first_byte_position(); | 308 byte_range_.last_byte_position() + 1 - byte_range_.first_byte_position(); |
263 set_expected_content_size(size); | 309 set_expected_content_size(size); |
264 remaining_bytes_ = size; | 310 remaining_bytes_ = size; |
265 | 311 |
266 // Create file stream reader. | 312 // Create file stream reader. |
267 stream_reader_ = file_system_context_->CreateFileStreamReader( | 313 stream_reader_ = file_system_context_->CreateFileStreamReader( |
268 file_system_url_, offset, size, base::Time()); | 314 file_system_url_, offset, size, base::Time()); |
mtomasz
2014/09/29 12:47:40
Could you briefly explain how it works? We're pass
hirono
2014/09/29 13:24:02
CreateFileStreamReader basically refers two member
mtomasz
2014/09/29 13:35:45
Got it. Thanks for the explanation.
| |
269 if (!stream_reader_) { | 315 if (!stream_reader_) { |
270 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 316 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
271 net::ERR_FILE_NOT_FOUND)); | 317 net::ERR_FILE_NOT_FOUND)); |
272 return; | 318 return; |
273 } | 319 } |
274 | 320 |
275 NotifyHeadersComplete(); | 321 NotifyHeadersComplete(); |
276 } | 322 } |
277 | 323 |
278 void ExternalFileURLRequestJob::Kill() { | 324 void ExternalFileURLRequestJob::Kill() { |
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
280 | 326 |
281 stream_reader_.reset(); | 327 stream_reader_.reset(); |
328 isolated_file_system_scope_.reset(); | |
282 file_system_context_ = NULL; | 329 file_system_context_ = NULL; |
283 net::URLRequestJob::Kill(); | 330 net::URLRequestJob::Kill(); |
284 weak_ptr_factory_.InvalidateWeakPtrs(); | 331 weak_ptr_factory_.InvalidateWeakPtrs(); |
285 } | 332 } |
286 | 333 |
287 bool ExternalFileURLRequestJob::GetMimeType(std::string* mime_type) const { | 334 bool ExternalFileURLRequestJob::GetMimeType(std::string* mime_type) const { |
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
289 mime_type->assign(mime_type_); | 336 mime_type->assign(mime_type_); |
290 return !mime_type->empty(); | 337 return !mime_type->empty(); |
291 } | 338 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 NotifyDone( | 395 NotifyDone( |
349 net::URLRequestStatus(net::URLRequestStatus::FAILED, read_result)); | 396 net::URLRequestStatus(net::URLRequestStatus::FAILED, read_result)); |
350 } | 397 } |
351 | 398 |
352 remaining_bytes_ -= read_result; | 399 remaining_bytes_ -= read_result; |
353 SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status. | 400 SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status. |
354 NotifyReadComplete(read_result); | 401 NotifyReadComplete(read_result); |
355 } | 402 } |
356 | 403 |
357 } // namespace chromeos | 404 } // namespace chromeos |
OLD | NEW |