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