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/file_system_operation.h" | 5 #include "webkit/fileapi/file_system_operation.h" |
6 | 6 |
7 #include "base/time.h" | 7 #include "base/time.h" |
8 #include "net/url_request/url_request_context.h" | 8 #include "net/url_request/url_request_context.h" |
9 #include "webkit/fileapi/file_system_callback_dispatcher.h" | 9 #include "webkit/fileapi/file_system_callback_dispatcher.h" |
10 #include "webkit/fileapi/file_system_context.h" | 10 #include "webkit/fileapi/file_system_context.h" |
11 #include "webkit/fileapi/file_system_file_util_proxy.h" | 11 #include "webkit/fileapi/file_system_file_util_proxy.h" |
12 #include "webkit/fileapi/file_system_operation_context.h" | 12 #include "webkit/fileapi/file_system_operation_context.h" |
13 #include "webkit/fileapi/file_system_path_manager.h" | 13 #include "webkit/fileapi/file_system_path_manager.h" |
| 14 #include "webkit/fileapi/file_system_util.h" |
14 #include "webkit/fileapi/file_writer_delegate.h" | 15 #include "webkit/fileapi/file_writer_delegate.h" |
| 16 #include "webkit/fileapi/local_file_system_file_util.h" |
15 | 17 |
16 namespace fileapi { | 18 namespace fileapi { |
17 | 19 |
18 FileSystemOperation::FileSystemOperation( | 20 FileSystemOperation::FileSystemOperation( |
19 FileSystemCallbackDispatcher* dispatcher, | 21 FileSystemCallbackDispatcher* dispatcher, |
20 scoped_refptr<base::MessageLoopProxy> proxy, | 22 scoped_refptr<base::MessageLoopProxy> proxy, |
21 FileSystemContext* file_system_context) | 23 FileSystemContext* file_system_context, |
| 24 FileSystemFileUtil* file_system_file_util) |
22 : proxy_(proxy), | 25 : proxy_(proxy), |
23 dispatcher_(dispatcher), | 26 dispatcher_(dispatcher), |
24 file_system_context_(file_system_context), | 27 file_system_operation_context_(file_system_context, |
25 file_system_operation_context_(FileSystemFileUtil::GetInstance()), | 28 file_system_file_util ? file_system_file_util : |
| 29 LocalFileSystemFileUtil::GetInstance()), |
26 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 30 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
27 DCHECK(dispatcher); | 31 DCHECK(dispatcher); |
28 #ifndef NDEBUG | 32 #ifndef NDEBUG |
29 pending_operation_ = kOperationNone; | 33 pending_operation_ = kOperationNone; |
30 #endif | 34 #endif |
31 } | 35 } |
32 | 36 |
33 FileSystemOperation::~FileSystemOperation() { | 37 FileSystemOperation::~FileSystemOperation() { |
34 if (file_writer_delegate_.get()) | 38 if (file_writer_delegate_.get()) |
35 FileSystemFileUtilProxy::Close( | 39 FileSystemFileUtilProxy::Close( |
36 file_system_operation_context_, | 40 file_system_operation_context_, |
37 proxy_, file_writer_delegate_->file(), NULL); | 41 proxy_, file_writer_delegate_->file(), NULL); |
38 } | 42 } |
39 | 43 |
40 void FileSystemOperation::OpenFileSystem( | 44 void FileSystemOperation::OpenFileSystem( |
41 const GURL& origin_url, fileapi::FileSystemType type, bool create) { | 45 const GURL& origin_url, fileapi::FileSystemType type, bool create) { |
42 #ifndef NDEBUG | 46 #ifndef NDEBUG |
43 DCHECK(kOperationNone == pending_operation_); | 47 DCHECK(kOperationNone == pending_operation_); |
44 pending_operation_ = static_cast<FileSystemOperation::OperationType>( | 48 pending_operation_ = static_cast<FileSystemOperation::OperationType>( |
45 kOperationOpenFileSystem); | 49 kOperationOpenFileSystem); |
46 #endif | 50 #endif |
47 | 51 |
48 DCHECK(file_system_context_.get()); | 52 DCHECK(file_system_context()); |
49 file_system_context_->path_manager()->GetFileSystemRootPath( | 53 file_system_operation_context_.set_src_origin_url(origin_url); |
| 54 file_system_operation_context_.set_src_type(type); |
| 55 // TODO(ericu): We don't really need to make this call if !create. |
| 56 // Also, in the future we won't need it either way, as long as we do all |
| 57 // permission+quota checks beforehand. We only need it now because we have to |
| 58 // create an unpredictable directory name. Without that, we could lazily |
| 59 // create the root later on the first filesystem write operation, and just |
| 60 // return GetFileSystemRootURI() here. |
| 61 file_system_context()->path_manager()->GetFileSystemRootPath( |
50 origin_url, type, create, | 62 origin_url, type, create, |
51 callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath)); | 63 callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath)); |
52 } | 64 } |
53 | 65 |
54 void FileSystemOperation::CreateFile(const FilePath& path, | 66 void FileSystemOperation::CreateFile(const FilePath& path, |
55 bool exclusive) { | 67 bool exclusive) { |
56 #ifndef NDEBUG | 68 #ifndef NDEBUG |
57 DCHECK(kOperationNone == pending_operation_); | 69 DCHECK(kOperationNone == pending_operation_); |
58 pending_operation_ = kOperationCreateFile; | 70 pending_operation_ = kOperationCreateFile; |
59 #endif | 71 #endif |
60 | 72 FilePath virtual_path; |
61 if (!VerifyFileSystemPathForWrite(path, true /* create */)) { | 73 GURL origin_url; |
| 74 FileSystemType type; |
| 75 if (!VerifyFileSystemPathForWrite( |
| 76 path, true /* create */, &origin_url, &type, &virtual_path)) { |
62 delete this; | 77 delete this; |
63 return; | 78 return; |
64 } | 79 } |
| 80 file_system_operation_context_.set_src_origin_url(origin_url); |
| 81 file_system_operation_context_.set_src_type(type); |
65 FileSystemFileUtilProxy::EnsureFileExists( | 82 FileSystemFileUtilProxy::EnsureFileExists( |
66 file_system_operation_context_, | 83 file_system_operation_context_, |
67 proxy_, path, callback_factory_.NewCallback( | 84 proxy_, virtual_path, callback_factory_.NewCallback( |
68 exclusive ? &FileSystemOperation::DidEnsureFileExistsExclusive | 85 exclusive ? &FileSystemOperation::DidEnsureFileExistsExclusive |
69 : &FileSystemOperation::DidEnsureFileExistsNonExclusive)); | 86 : &FileSystemOperation::DidEnsureFileExistsNonExclusive)); |
70 } | 87 } |
71 | 88 |
72 void FileSystemOperation::CreateDirectory(const FilePath& path, | 89 void FileSystemOperation::CreateDirectory(const FilePath& path, |
73 bool exclusive, | 90 bool exclusive, |
74 bool recursive) { | 91 bool recursive) { |
75 #ifndef NDEBUG | 92 #ifndef NDEBUG |
76 DCHECK(kOperationNone == pending_operation_); | 93 DCHECK(kOperationNone == pending_operation_); |
77 pending_operation_ = kOperationCreateDirectory; | 94 pending_operation_ = kOperationCreateDirectory; |
78 #endif | 95 #endif |
| 96 FilePath virtual_path; |
| 97 GURL origin_url; |
| 98 FileSystemType type; |
79 | 99 |
80 if (!VerifyFileSystemPathForWrite(path, true /* create */)) { | 100 if (!VerifyFileSystemPathForWrite( |
| 101 path, true /* create */, &origin_url, &type, &virtual_path)) { |
81 delete this; | 102 delete this; |
82 return; | 103 return; |
83 } | 104 } |
| 105 file_system_operation_context_.set_src_origin_url(origin_url); |
| 106 file_system_operation_context_.set_src_type(type); |
84 FileSystemFileUtilProxy::CreateDirectory( | 107 FileSystemFileUtilProxy::CreateDirectory( |
85 file_system_operation_context_, | 108 file_system_operation_context_, |
86 proxy_, path, exclusive, recursive, callback_factory_.NewCallback( | 109 proxy_, virtual_path, exclusive, recursive, callback_factory_.NewCallback( |
87 &FileSystemOperation::DidFinishFileOperation)); | 110 &FileSystemOperation::DidFinishFileOperation)); |
88 } | 111 } |
89 | 112 |
90 void FileSystemOperation::Copy(const FilePath& src_path, | 113 void FileSystemOperation::Copy(const FilePath& src_path, |
91 const FilePath& dest_path) { | 114 const FilePath& dest_path) { |
92 #ifndef NDEBUG | 115 #ifndef NDEBUG |
93 DCHECK(kOperationNone == pending_operation_); | 116 DCHECK(kOperationNone == pending_operation_); |
94 pending_operation_ = kOperationCopy; | 117 pending_operation_ = kOperationCopy; |
95 #endif | 118 #endif |
| 119 FilePath virtual_path_0; |
| 120 FilePath virtual_path_1; |
| 121 GURL src_origin_url; |
| 122 GURL dest_origin_url; |
| 123 FileSystemType src_type; |
| 124 FileSystemType dest_type; |
96 | 125 |
97 if (!VerifyFileSystemPathForRead(src_path) || | 126 if (!VerifyFileSystemPathForRead(src_path, &src_origin_url, &src_type, |
98 !VerifyFileSystemPathForWrite(dest_path, true /* create */)) { | 127 &virtual_path_0) || |
| 128 !VerifyFileSystemPathForWrite(dest_path, true /* create */, |
| 129 &dest_origin_url, &dest_type, &virtual_path_1)) { |
99 delete this; | 130 delete this; |
100 return; | 131 return; |
101 } | 132 } |
| 133 if (src_origin_url.GetOrigin() != dest_origin_url.GetOrigin()) { |
| 134 // TODO(ericu): We don't yet support copying across filesystem types, from |
| 135 // extension to sandbox, etc. From temporary to persistent works, though. |
| 136 // Since the sandbox code isn't in yet, I'm not sure exactly what check |
| 137 // belongs here, but there's also no danger yet. |
| 138 delete this; |
| 139 return; |
| 140 } |
| 141 file_system_operation_context_.set_src_origin_url(src_origin_url); |
| 142 file_system_operation_context_.set_dest_origin_url(dest_origin_url); |
| 143 file_system_operation_context_.set_src_type(src_type); |
| 144 file_system_operation_context_.set_dest_type(dest_type); |
102 FileSystemFileUtilProxy::Copy( | 145 FileSystemFileUtilProxy::Copy( |
103 file_system_operation_context_, | 146 file_system_operation_context_, |
104 proxy_, src_path, dest_path, callback_factory_.NewCallback( | 147 proxy_, virtual_path_0, virtual_path_1, |
105 &FileSystemOperation::DidFinishFileOperation)); | 148 callback_factory_.NewCallback( |
| 149 &FileSystemOperation::DidFinishFileOperation)); |
106 } | 150 } |
107 | 151 |
108 void FileSystemOperation::Move(const FilePath& src_path, | 152 void FileSystemOperation::Move(const FilePath& src_path, |
109 const FilePath& dest_path) { | 153 const FilePath& dest_path) { |
110 #ifndef NDEBUG | 154 #ifndef NDEBUG |
111 DCHECK(kOperationNone == pending_operation_); | 155 DCHECK(kOperationNone == pending_operation_); |
112 pending_operation_ = kOperationMove; | 156 pending_operation_ = kOperationMove; |
113 #endif | 157 #endif |
| 158 FilePath virtual_path_0; |
| 159 FilePath virtual_path_1; |
| 160 GURL src_origin_url; |
| 161 GURL dest_origin_url; |
| 162 FileSystemType src_type; |
| 163 FileSystemType dest_type; |
114 | 164 |
115 if (!VerifyFileSystemPathForRead(src_path) || | 165 if (!VerifyFileSystemPathForRead(src_path, &src_origin_url, &src_type, |
116 !VerifyFileSystemPathForWrite(dest_path, true /* create */)) { | 166 &virtual_path_0) || |
| 167 !VerifyFileSystemPathForWrite(dest_path, true /* create */, |
| 168 &dest_origin_url, &dest_type, &virtual_path_1)) { |
117 delete this; | 169 delete this; |
118 return; | 170 return; |
119 } | 171 } |
| 172 if (src_origin_url.GetOrigin() != dest_origin_url.GetOrigin()) { |
| 173 // TODO(ericu): We don't yet support moving across filesystem types, from |
| 174 // extension to sandbox, etc. From temporary to persistent works, though. |
| 175 delete this; |
| 176 return; |
| 177 } |
| 178 file_system_operation_context_.set_src_origin_url(src_origin_url); |
| 179 file_system_operation_context_.set_dest_origin_url(dest_origin_url); |
| 180 file_system_operation_context_.set_src_type(src_type); |
| 181 file_system_operation_context_.set_dest_type(dest_type); |
120 FileSystemFileUtilProxy::Move( | 182 FileSystemFileUtilProxy::Move( |
121 file_system_operation_context_, | 183 file_system_operation_context_, |
122 proxy_, src_path, dest_path, callback_factory_.NewCallback( | 184 proxy_, virtual_path_0, virtual_path_1, |
123 &FileSystemOperation::DidFinishFileOperation)); | 185 callback_factory_.NewCallback( |
| 186 &FileSystemOperation::DidFinishFileOperation)); |
124 } | 187 } |
125 | 188 |
126 void FileSystemOperation::DirectoryExists(const FilePath& path) { | 189 void FileSystemOperation::DirectoryExists(const FilePath& path) { |
127 #ifndef NDEBUG | 190 #ifndef NDEBUG |
128 DCHECK(kOperationNone == pending_operation_); | 191 DCHECK(kOperationNone == pending_operation_); |
129 pending_operation_ = kOperationDirectoryExists; | 192 pending_operation_ = kOperationDirectoryExists; |
130 #endif | 193 #endif |
131 | 194 |
132 if (!VerifyFileSystemPathForRead(path)) { | 195 FilePath virtual_path; |
| 196 GURL origin_url; |
| 197 FileSystemType type; |
| 198 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
133 delete this; | 199 delete this; |
134 return; | 200 return; |
135 } | 201 } |
| 202 file_system_operation_context_.set_src_origin_url(origin_url); |
| 203 file_system_operation_context_.set_src_type(type); |
136 FileSystemFileUtilProxy::GetFileInfo( | 204 FileSystemFileUtilProxy::GetFileInfo( |
137 file_system_operation_context_, | 205 file_system_operation_context_, |
138 proxy_, path, callback_factory_.NewCallback( | 206 proxy_, virtual_path, callback_factory_.NewCallback( |
139 &FileSystemOperation::DidDirectoryExists)); | 207 &FileSystemOperation::DidDirectoryExists)); |
140 } | 208 } |
141 | 209 |
142 void FileSystemOperation::FileExists(const FilePath& path) { | 210 void FileSystemOperation::FileExists(const FilePath& path) { |
143 #ifndef NDEBUG | 211 #ifndef NDEBUG |
144 DCHECK(kOperationNone == pending_operation_); | 212 DCHECK(kOperationNone == pending_operation_); |
145 pending_operation_ = kOperationFileExists; | 213 pending_operation_ = kOperationFileExists; |
146 #endif | 214 #endif |
147 | 215 |
148 if (!VerifyFileSystemPathForRead(path)) { | 216 FilePath virtual_path; |
| 217 GURL origin_url; |
| 218 FileSystemType type; |
| 219 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
149 delete this; | 220 delete this; |
150 return; | 221 return; |
151 } | 222 } |
| 223 file_system_operation_context_.set_src_origin_url(origin_url); |
| 224 file_system_operation_context_.set_src_type(type); |
152 FileSystemFileUtilProxy::GetFileInfo( | 225 FileSystemFileUtilProxy::GetFileInfo( |
153 file_system_operation_context_, | 226 file_system_operation_context_, |
154 proxy_, path, callback_factory_.NewCallback( | 227 proxy_, virtual_path, callback_factory_.NewCallback( |
155 &FileSystemOperation::DidFileExists)); | 228 &FileSystemOperation::DidFileExists)); |
156 } | 229 } |
157 | 230 |
158 void FileSystemOperation::GetMetadata(const FilePath& path) { | 231 void FileSystemOperation::GetMetadata(const FilePath& path) { |
159 #ifndef NDEBUG | 232 #ifndef NDEBUG |
160 DCHECK(kOperationNone == pending_operation_); | 233 DCHECK(kOperationNone == pending_operation_); |
161 pending_operation_ = kOperationGetMetadata; | 234 pending_operation_ = kOperationGetMetadata; |
162 #endif | 235 #endif |
163 | 236 |
164 if (!VerifyFileSystemPathForRead(path)) { | 237 FilePath virtual_path; |
| 238 GURL origin_url; |
| 239 FileSystemType type; |
| 240 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
165 delete this; | 241 delete this; |
166 return; | 242 return; |
167 } | 243 } |
| 244 file_system_operation_context_.set_src_origin_url(origin_url); |
| 245 file_system_operation_context_.set_src_type(type); |
168 FileSystemFileUtilProxy::GetFileInfo( | 246 FileSystemFileUtilProxy::GetFileInfo( |
169 file_system_operation_context_, | 247 file_system_operation_context_, |
170 proxy_, path, callback_factory_.NewCallback( | 248 proxy_, virtual_path, callback_factory_.NewCallback( |
171 &FileSystemOperation::DidGetMetadata)); | 249 &FileSystemOperation::DidGetMetadata)); |
172 } | 250 } |
173 | 251 |
174 void FileSystemOperation::ReadDirectory(const FilePath& path) { | 252 void FileSystemOperation::ReadDirectory(const FilePath& path) { |
175 #ifndef NDEBUG | 253 #ifndef NDEBUG |
176 DCHECK(kOperationNone == pending_operation_); | 254 DCHECK(kOperationNone == pending_operation_); |
177 pending_operation_ = kOperationReadDirectory; | 255 pending_operation_ = kOperationReadDirectory; |
178 #endif | 256 #endif |
179 | 257 |
180 if (!VerifyFileSystemPathForRead(path)) { | 258 FilePath virtual_path; |
| 259 GURL origin_url; |
| 260 FileSystemType type; |
| 261 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
181 delete this; | 262 delete this; |
182 return; | 263 return; |
183 } | 264 } |
| 265 file_system_operation_context_.set_src_origin_url(origin_url); |
| 266 file_system_operation_context_.set_src_type(type); |
184 FileSystemFileUtilProxy::ReadDirectory( | 267 FileSystemFileUtilProxy::ReadDirectory( |
185 file_system_operation_context_, | 268 file_system_operation_context_, |
186 proxy_, path, callback_factory_.NewCallback( | 269 proxy_, virtual_path, callback_factory_.NewCallback( |
187 &FileSystemOperation::DidReadDirectory)); | 270 &FileSystemOperation::DidReadDirectory)); |
188 } | 271 } |
189 | 272 |
190 void FileSystemOperation::Remove(const FilePath& path, bool recursive) { | 273 void FileSystemOperation::Remove(const FilePath& path, bool recursive) { |
191 #ifndef NDEBUG | 274 #ifndef NDEBUG |
192 DCHECK(kOperationNone == pending_operation_); | 275 DCHECK(kOperationNone == pending_operation_); |
193 pending_operation_ = kOperationRemove; | 276 pending_operation_ = kOperationRemove; |
194 #endif | 277 #endif |
195 | 278 |
196 if (!VerifyFileSystemPathForWrite(path, false /* create */)) { | 279 FilePath virtual_path; |
| 280 GURL origin_url; |
| 281 FileSystemType type; |
| 282 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, |
| 283 &type, &virtual_path)) { |
197 delete this; | 284 delete this; |
198 return; | 285 return; |
199 } | 286 } |
| 287 file_system_operation_context_.set_src_origin_url(origin_url); |
| 288 file_system_operation_context_.set_src_type(type); |
200 FileSystemFileUtilProxy::Delete( | 289 FileSystemFileUtilProxy::Delete( |
201 file_system_operation_context_, | 290 file_system_operation_context_, |
202 proxy_, path, recursive, callback_factory_.NewCallback( | 291 proxy_, virtual_path, recursive, callback_factory_.NewCallback( |
203 &FileSystemOperation::DidFinishFileOperation)); | 292 &FileSystemOperation::DidFinishFileOperation)); |
204 } | 293 } |
205 | 294 |
206 void FileSystemOperation::Write( | 295 void FileSystemOperation::Write( |
207 scoped_refptr<net::URLRequestContext> url_request_context, | 296 scoped_refptr<net::URLRequestContext> url_request_context, |
208 const FilePath& path, | 297 const FilePath& path, |
209 const GURL& blob_url, | 298 const GURL& blob_url, |
210 int64 offset) { | 299 int64 offset) { |
211 #ifndef NDEBUG | 300 #ifndef NDEBUG |
212 DCHECK(kOperationNone == pending_operation_); | 301 DCHECK(kOperationNone == pending_operation_); |
213 pending_operation_ = kOperationWrite; | 302 pending_operation_ = kOperationWrite; |
214 #endif | 303 #endif |
215 if (!VerifyFileSystemPathForWrite(path, true /* create */)) { | 304 FilePath virtual_path; |
| 305 GURL origin_url; |
| 306 FileSystemType type; |
| 307 if (!VerifyFileSystemPathForWrite(path, true /* create */, &origin_url, |
| 308 &type, &virtual_path)) { |
216 delete this; | 309 delete this; |
217 return; | 310 return; |
218 } | 311 } |
| 312 file_system_operation_context_.set_src_origin_url(origin_url); |
| 313 file_system_operation_context_.set_src_type(type); |
219 DCHECK(blob_url.is_valid()); | 314 DCHECK(blob_url.is_valid()); |
220 file_writer_delegate_.reset(new FileWriterDelegate(this, offset)); | 315 file_writer_delegate_.reset(new FileWriterDelegate(this, offset)); |
221 blob_request_.reset( | 316 blob_request_.reset( |
222 new net::URLRequest(blob_url, file_writer_delegate_.get())); | 317 new net::URLRequest(blob_url, file_writer_delegate_.get())); |
223 blob_request_->set_context(url_request_context); | 318 blob_request_->set_context(url_request_context); |
224 FileSystemFileUtilProxy::CreateOrOpen( | 319 FileSystemFileUtilProxy::CreateOrOpen( |
225 file_system_operation_context_, | 320 file_system_operation_context_, |
226 proxy_, | 321 proxy_, |
227 path, | 322 virtual_path, |
228 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | | 323 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | |
229 base::PLATFORM_FILE_ASYNC, | 324 base::PLATFORM_FILE_ASYNC, |
230 callback_factory_.NewCallback( | 325 callback_factory_.NewCallback( |
231 &FileSystemOperation::OnFileOpenedForWrite)); | 326 &FileSystemOperation::OnFileOpenedForWrite)); |
232 } | 327 } |
233 | 328 |
234 void FileSystemOperation::Truncate(const FilePath& path, int64 length) { | 329 void FileSystemOperation::Truncate(const FilePath& path, int64 length) { |
235 #ifndef NDEBUG | 330 #ifndef NDEBUG |
236 DCHECK(kOperationNone == pending_operation_); | 331 DCHECK(kOperationNone == pending_operation_); |
237 pending_operation_ = kOperationTruncate; | 332 pending_operation_ = kOperationTruncate; |
238 #endif | 333 #endif |
239 if (!VerifyFileSystemPathForWrite(path, false /* create */)) { | 334 FilePath virtual_path; |
| 335 GURL origin_url; |
| 336 FileSystemType type; |
| 337 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, |
| 338 &type, &virtual_path)) { |
240 delete this; | 339 delete this; |
241 return; | 340 return; |
242 } | 341 } |
| 342 file_system_operation_context_.set_src_origin_url(origin_url); |
| 343 file_system_operation_context_.set_src_type(type); |
243 FileSystemFileUtilProxy::Truncate( | 344 FileSystemFileUtilProxy::Truncate( |
244 file_system_operation_context_, | 345 file_system_operation_context_, |
245 proxy_, path, length, callback_factory_.NewCallback( | 346 proxy_, virtual_path, length, callback_factory_.NewCallback( |
246 &FileSystemOperation::DidFinishFileOperation)); | 347 &FileSystemOperation::DidFinishFileOperation)); |
247 } | 348 } |
248 | 349 |
249 void FileSystemOperation::TouchFile(const FilePath& path, | 350 void FileSystemOperation::TouchFile(const FilePath& path, |
250 const base::Time& last_access_time, | 351 const base::Time& last_access_time, |
251 const base::Time& last_modified_time) { | 352 const base::Time& last_modified_time) { |
252 #ifndef NDEBUG | 353 #ifndef NDEBUG |
253 DCHECK(kOperationNone == pending_operation_); | 354 DCHECK(kOperationNone == pending_operation_); |
254 pending_operation_ = kOperationTouchFile; | 355 pending_operation_ = kOperationTouchFile; |
255 #endif | 356 #endif |
256 | 357 |
257 if (!VerifyFileSystemPathForWrite(path, true /* create */)) { | 358 FilePath virtual_path; |
| 359 GURL origin_url; |
| 360 FileSystemType type; |
| 361 if (!VerifyFileSystemPathForWrite(path, true /* create */, &origin_url, |
| 362 &type, &virtual_path)) { |
258 delete this; | 363 delete this; |
259 return; | 364 return; |
260 } | 365 } |
| 366 file_system_operation_context_.set_src_origin_url(origin_url); |
| 367 file_system_operation_context_.set_src_type(type); |
261 FileSystemFileUtilProxy::Touch( | 368 FileSystemFileUtilProxy::Touch( |
262 file_system_operation_context_, | 369 file_system_operation_context_, |
263 proxy_, path, last_access_time, last_modified_time, | 370 proxy_, virtual_path, last_access_time, last_modified_time, |
264 callback_factory_.NewCallback(&FileSystemOperation::DidTouchFile)); | 371 callback_factory_.NewCallback(&FileSystemOperation::DidTouchFile)); |
265 } | 372 } |
266 | 373 |
267 // We can only get here on a write or truncate that's not yet completed. | 374 // We can only get here on a write or truncate that's not yet completed. |
268 // We don't support cancelling any other operation at this time. | 375 // We don't support cancelling any other operation at this time. |
269 void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) { | 376 void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) { |
270 scoped_ptr<FileSystemOperation> cancel_operation(cancel_operation_ptr); | 377 scoped_ptr<FileSystemOperation> cancel_operation(cancel_operation_ptr); |
271 if (file_writer_delegate_.get()) { | 378 if (file_writer_delegate_.get()) { |
272 #ifndef NDEBUG | 379 #ifndef NDEBUG |
273 DCHECK(kOperationWrite == pending_operation_); | 380 DCHECK(kOperationWrite == pending_operation_); |
(...skipping 19 matching lines...) Expand all Loading... |
293 // cancel_operation so that when the truncate returns, it can see that it's | 400 // cancel_operation so that when the truncate returns, it can see that it's |
294 // been cancelled, report it, and report that the cancel has succeeded. | 401 // been cancelled, report it, and report that the cancel has succeeded. |
295 DCHECK(!cancel_operation_.get()); | 402 DCHECK(!cancel_operation_.get()); |
296 cancel_operation_.swap(cancel_operation); | 403 cancel_operation_.swap(cancel_operation); |
297 } | 404 } |
298 } | 405 } |
299 | 406 |
300 void FileSystemOperation::DidGetRootPath( | 407 void FileSystemOperation::DidGetRootPath( |
301 bool success, const FilePath& path, const std::string& name) { | 408 bool success, const FilePath& path, const std::string& name) { |
302 DCHECK(success || path.empty()); | 409 DCHECK(success || path.empty()); |
303 dispatcher_->DidOpenFileSystem(name, path); | 410 FilePath result; |
| 411 // We ignore the path, and return a URL instead. The point was just to verify |
| 412 // that we could create/find the path. |
| 413 if (success) { |
| 414 GURL root_url = GetFileSystemRootURI( |
| 415 file_system_operation_context_.src_origin_url(), |
| 416 file_system_operation_context_.src_type()); |
| 417 result = FilePath().AppendASCII(root_url.spec()); |
| 418 } |
| 419 dispatcher_->DidOpenFileSystem(name, result); |
304 delete this; | 420 delete this; |
305 } | 421 } |
306 | 422 |
307 void FileSystemOperation::DidEnsureFileExistsExclusive( | 423 void FileSystemOperation::DidEnsureFileExistsExclusive( |
308 base::PlatformFileError rv, bool created) { | 424 base::PlatformFileError rv, bool created) { |
309 if (rv == base::PLATFORM_FILE_OK && !created) { | 425 if (rv == base::PLATFORM_FILE_OK && !created) { |
310 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); | 426 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); |
311 delete this; | 427 delete this; |
312 } else | 428 } else |
313 DidFinishFileOperation(rv); | 429 DidFinishFileOperation(rv); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 bool created) { | 525 bool created) { |
410 if (base::PLATFORM_FILE_OK != rv) { | 526 if (base::PLATFORM_FILE_OK != rv) { |
411 dispatcher_->DidFail(rv); | 527 dispatcher_->DidFail(rv); |
412 delete this; | 528 delete this; |
413 return; | 529 return; |
414 } | 530 } |
415 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); | 531 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); |
416 } | 532 } |
417 | 533 |
418 bool FileSystemOperation::VerifyFileSystemPathForRead( | 534 bool FileSystemOperation::VerifyFileSystemPathForRead( |
419 const FilePath& path) { | 535 const FilePath& path, GURL* origin_url, FileSystemType* type, |
420 // If we have no context, we just allow any operations. | 536 FilePath* virtual_path) { |
421 if (!file_system_context_.get()) | 537 |
| 538 // If we have no context, we just allow any operations, for testing. |
| 539 // TODO(ericu): Revisit this hack for security. |
| 540 if (!file_system_context()) { |
| 541 *virtual_path = path; |
| 542 *type = file_system_operation_context_.src_type(); |
422 return true; | 543 return true; |
| 544 } |
423 | 545 |
424 // We may want do more checks, but for now it just checks if the given | 546 // We may want do more checks, but for now it just checks if the given |
425 // |path| is under the valid FileSystem root path for this host context. | 547 // |path| is under the valid FileSystem root path for this host context. |
426 if (!file_system_context_->path_manager()->CrackFileSystemPath( | 548 if (!file_system_context()->path_manager()->CrackFileSystemPath( |
427 path, NULL, NULL, NULL)) { | 549 path, origin_url, type, virtual_path)) { |
428 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 550 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
429 return false; | 551 return false; |
430 } | 552 } |
431 return true; | 553 return true; |
432 } | 554 } |
433 | 555 |
434 bool FileSystemOperation::VerifyFileSystemPathForWrite( | 556 bool FileSystemOperation::VerifyFileSystemPathForWrite( |
435 const FilePath& path, bool create) { | 557 const FilePath& path, bool create, GURL* origin_url, FileSystemType* type, |
436 GURL origin_url; | 558 FilePath* virtual_path) { |
437 FilePath virtual_path; | |
438 | 559 |
439 // If we have no context, we just allow any operations. | 560 // If we have no context, we just allow any operations, for testing. |
440 if (!file_system_context_.get()) | 561 // TODO(ericu): Revisit this hack for security. |
| 562 if (!file_system_context()) { |
| 563 *virtual_path = path; |
| 564 *type = file_system_operation_context_.dest_type(); |
441 return true; | 565 return true; |
| 566 } |
442 | 567 |
443 if (!file_system_context_->path_manager()->CrackFileSystemPath( | 568 if (!file_system_context()->path_manager()->CrackFileSystemPath( |
444 path, &origin_url, NULL, &virtual_path)) { | 569 path, origin_url, type, virtual_path)) { |
445 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 570 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
446 return false; | 571 return false; |
447 } | 572 } |
448 // Any write access is disallowed on the root path. | 573 // Any write access is disallowed on the root path. |
449 if (virtual_path.value().length() == 0 || | 574 if (virtual_path->value().length() == 0 || |
450 virtual_path.DirName().value() == virtual_path.value()) { | 575 virtual_path->DirName().value() == virtual_path->value()) { |
451 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 576 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
452 return false; | 577 return false; |
453 } | 578 } |
454 if (create && FileSystemPathManager::IsRestrictedFileName( | 579 if (create && file_system_context()->path_manager()->IsRestrictedFileName( |
455 path.BaseName())) { | 580 *type, virtual_path->BaseName())) { |
456 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 581 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
457 return false; | 582 return false; |
458 } | 583 } |
459 // TODO(kinuko): the check must be moved to QuotaFileSystemFileUtil. | 584 // TODO(kinuko): the check must be moved to QuotaFileSystemFileUtil. |
460 if (!file_system_context_->IsStorageUnlimited(origin_url)) { | 585 if (!file_system_context()->IsStorageUnlimited(*origin_url)) { |
461 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); | 586 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); |
462 return false; | 587 return false; |
463 } | 588 } |
464 return true; | 589 return true; |
465 } | 590 } |
466 | 591 |
467 } // namespace fileapi | 592 } // namespace fileapi |
OLD | NEW |