| 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 "base/utf_string_conversions.h" |
| 9 #include "net/base/escape.h" |
| 8 #include "net/url_request/url_request_context.h" | 10 #include "net/url_request/url_request_context.h" |
| 9 #include "webkit/fileapi/file_system_callback_dispatcher.h" | 11 #include "webkit/fileapi/file_system_callback_dispatcher.h" |
| 10 #include "webkit/fileapi/file_system_context.h" | 12 #include "webkit/fileapi/file_system_context.h" |
| 11 #include "webkit/fileapi/file_system_file_util_proxy.h" | 13 #include "webkit/fileapi/file_system_file_util_proxy.h" |
| 12 #include "webkit/fileapi/file_system_operation_context.h" | 14 #include "webkit/fileapi/file_system_operation_context.h" |
| 13 #include "webkit/fileapi/file_system_path_manager.h" | 15 #include "webkit/fileapi/file_system_path_manager.h" |
| 14 #include "webkit/fileapi/file_system_util.h" | 16 #include "webkit/fileapi/file_system_util.h" |
| 15 #include "webkit/fileapi/file_writer_delegate.h" | 17 #include "webkit/fileapi/file_writer_delegate.h" |
| 16 #include "webkit/fileapi/local_file_system_file_util.h" | 18 #include "webkit/fileapi/local_file_system_file_util.h" |
| 17 | 19 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 // Also, in the future we won't need it either way, as long as we do all | 58 // 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 | 59 // permission+quota checks beforehand. We only need it now because we have to |
| 58 // create an unpredictable directory name. Without that, we could lazily | 60 // create an unpredictable directory name. Without that, we could lazily |
| 59 // create the root later on the first filesystem write operation, and just | 61 // create the root later on the first filesystem write operation, and just |
| 60 // return GetFileSystemRootURI() here. | 62 // return GetFileSystemRootURI() here. |
| 61 file_system_context()->path_manager()->GetFileSystemRootPath( | 63 file_system_context()->path_manager()->GetFileSystemRootPath( |
| 62 origin_url, type, create, | 64 origin_url, type, create, |
| 63 callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath)); | 65 callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath)); |
| 64 } | 66 } |
| 65 | 67 |
| 66 void FileSystemOperation::CreateFile(const FilePath& path, | 68 void FileSystemOperation::CreateFile(const GURL& path, |
| 67 bool exclusive) { | 69 bool exclusive) { |
| 68 #ifndef NDEBUG | 70 #ifndef NDEBUG |
| 69 DCHECK(kOperationNone == pending_operation_); | 71 DCHECK(kOperationNone == pending_operation_); |
| 70 pending_operation_ = kOperationCreateFile; | 72 pending_operation_ = kOperationCreateFile; |
| 71 #endif | 73 #endif |
| 72 FilePath virtual_path; | 74 FilePath virtual_path; |
| 73 GURL origin_url; | 75 GURL origin_url; |
| 74 FileSystemType type; | 76 FileSystemType type; |
| 75 if (!VerifyFileSystemPathForWrite( | 77 if (!VerifyFileSystemPathForWrite( |
| 76 path, true /* create */, &origin_url, &type, &virtual_path)) { | 78 path, true /* create */, &origin_url, &type, &virtual_path)) { |
| 77 delete this; | 79 delete this; |
| 78 return; | 80 return; |
| 79 } | 81 } |
| 80 file_system_operation_context_.set_src_origin_url(origin_url); | 82 file_system_operation_context_.set_src_origin_url(origin_url); |
| 81 file_system_operation_context_.set_src_type(type); | 83 file_system_operation_context_.set_src_type(type); |
| 82 FileSystemFileUtilProxy::EnsureFileExists( | 84 FileSystemFileUtilProxy::EnsureFileExists( |
| 83 file_system_operation_context_, | 85 file_system_operation_context_, |
| 84 proxy_, virtual_path, callback_factory_.NewCallback( | 86 proxy_, virtual_path, callback_factory_.NewCallback( |
| 85 exclusive ? &FileSystemOperation::DidEnsureFileExistsExclusive | 87 exclusive ? &FileSystemOperation::DidEnsureFileExistsExclusive |
| 86 : &FileSystemOperation::DidEnsureFileExistsNonExclusive)); | 88 : &FileSystemOperation::DidEnsureFileExistsNonExclusive)); |
| 87 } | 89 } |
| 88 | 90 |
| 89 void FileSystemOperation::CreateDirectory(const FilePath& path, | 91 void FileSystemOperation::CreateDirectory(const GURL& path, |
| 90 bool exclusive, | 92 bool exclusive, |
| 91 bool recursive) { | 93 bool recursive) { |
| 92 #ifndef NDEBUG | 94 #ifndef NDEBUG |
| 93 DCHECK(kOperationNone == pending_operation_); | 95 DCHECK(kOperationNone == pending_operation_); |
| 94 pending_operation_ = kOperationCreateDirectory; | 96 pending_operation_ = kOperationCreateDirectory; |
| 95 #endif | 97 #endif |
| 96 FilePath virtual_path; | 98 FilePath virtual_path; |
| 97 GURL origin_url; | 99 GURL origin_url; |
| 98 FileSystemType type; | 100 FileSystemType type; |
| 99 | 101 |
| 100 if (!VerifyFileSystemPathForWrite( | 102 if (!VerifyFileSystemPathForWrite( |
| 101 path, true /* create */, &origin_url, &type, &virtual_path)) { | 103 path, true /* create */, &origin_url, &type, &virtual_path)) { |
| 102 delete this; | 104 delete this; |
| 103 return; | 105 return; |
| 104 } | 106 } |
| 105 file_system_operation_context_.set_src_origin_url(origin_url); | 107 file_system_operation_context_.set_src_origin_url(origin_url); |
| 106 file_system_operation_context_.set_src_type(type); | 108 file_system_operation_context_.set_src_type(type); |
| 107 FileSystemFileUtilProxy::CreateDirectory( | 109 FileSystemFileUtilProxy::CreateDirectory( |
| 108 file_system_operation_context_, | 110 file_system_operation_context_, |
| 109 proxy_, virtual_path, exclusive, recursive, callback_factory_.NewCallback( | 111 proxy_, virtual_path, exclusive, recursive, callback_factory_.NewCallback( |
| 110 &FileSystemOperation::DidFinishFileOperation)); | 112 &FileSystemOperation::DidFinishFileOperation)); |
| 111 } | 113 } |
| 112 | 114 |
| 113 void FileSystemOperation::Copy(const FilePath& src_path, | 115 void FileSystemOperation::Copy(const GURL& src_path, |
| 114 const FilePath& dest_path) { | 116 const GURL& dest_path) { |
| 115 #ifndef NDEBUG | 117 #ifndef NDEBUG |
| 116 DCHECK(kOperationNone == pending_operation_); | 118 DCHECK(kOperationNone == pending_operation_); |
| 117 pending_operation_ = kOperationCopy; | 119 pending_operation_ = kOperationCopy; |
| 118 #endif | 120 #endif |
| 119 FilePath virtual_path_0; | 121 FilePath virtual_path_0; |
| 120 FilePath virtual_path_1; | 122 FilePath virtual_path_1; |
| 121 GURL src_origin_url; | 123 GURL src_origin_url; |
| 122 GURL dest_origin_url; | 124 GURL dest_origin_url; |
| 123 FileSystemType src_type; | 125 FileSystemType src_type; |
| 124 FileSystemType dest_type; | 126 FileSystemType dest_type; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 142 file_system_operation_context_.set_dest_origin_url(dest_origin_url); | 144 file_system_operation_context_.set_dest_origin_url(dest_origin_url); |
| 143 file_system_operation_context_.set_src_type(src_type); | 145 file_system_operation_context_.set_src_type(src_type); |
| 144 file_system_operation_context_.set_dest_type(dest_type); | 146 file_system_operation_context_.set_dest_type(dest_type); |
| 145 FileSystemFileUtilProxy::Copy( | 147 FileSystemFileUtilProxy::Copy( |
| 146 file_system_operation_context_, | 148 file_system_operation_context_, |
| 147 proxy_, virtual_path_0, virtual_path_1, | 149 proxy_, virtual_path_0, virtual_path_1, |
| 148 callback_factory_.NewCallback( | 150 callback_factory_.NewCallback( |
| 149 &FileSystemOperation::DidFinishFileOperation)); | 151 &FileSystemOperation::DidFinishFileOperation)); |
| 150 } | 152 } |
| 151 | 153 |
| 152 void FileSystemOperation::Move(const FilePath& src_path, | 154 void FileSystemOperation::Move(const GURL& src_path, |
| 153 const FilePath& dest_path) { | 155 const GURL& dest_path) { |
| 154 #ifndef NDEBUG | 156 #ifndef NDEBUG |
| 155 DCHECK(kOperationNone == pending_operation_); | 157 DCHECK(kOperationNone == pending_operation_); |
| 156 pending_operation_ = kOperationMove; | 158 pending_operation_ = kOperationMove; |
| 157 #endif | 159 #endif |
| 158 FilePath virtual_path_0; | 160 FilePath virtual_path_0; |
| 159 FilePath virtual_path_1; | 161 FilePath virtual_path_1; |
| 160 GURL src_origin_url; | 162 GURL src_origin_url; |
| 161 GURL dest_origin_url; | 163 GURL dest_origin_url; |
| 162 FileSystemType src_type; | 164 FileSystemType src_type; |
| 163 FileSystemType dest_type; | 165 FileSystemType dest_type; |
| 164 | 166 |
| 167 //TODO(ericu): Move alters the source path as well, so we should be checking |
| 168 //both for write! |
| 165 if (!VerifyFileSystemPathForRead(src_path, &src_origin_url, &src_type, | 169 if (!VerifyFileSystemPathForRead(src_path, &src_origin_url, &src_type, |
| 166 &virtual_path_0) || | 170 &virtual_path_0) || |
| 167 !VerifyFileSystemPathForWrite(dest_path, true /* create */, | 171 !VerifyFileSystemPathForWrite(dest_path, true /* create */, |
| 168 &dest_origin_url, &dest_type, &virtual_path_1)) { | 172 &dest_origin_url, &dest_type, &virtual_path_1)) { |
| 169 delete this; | 173 delete this; |
| 170 return; | 174 return; |
| 171 } | 175 } |
| 172 if (src_origin_url.GetOrigin() != dest_origin_url.GetOrigin()) { | 176 if (src_origin_url.GetOrigin() != dest_origin_url.GetOrigin()) { |
| 173 // TODO(ericu): We don't yet support moving across filesystem types, from | 177 // TODO(ericu): We don't yet support moving across filesystem types, from |
| 174 // extension to sandbox, etc. From temporary to persistent works, though. | 178 // extension to sandbox, etc. From temporary to persistent works, though. |
| 175 delete this; | 179 delete this; |
| 176 return; | 180 return; |
| 177 } | 181 } |
| 178 file_system_operation_context_.set_src_origin_url(src_origin_url); | 182 file_system_operation_context_.set_src_origin_url(src_origin_url); |
| 179 file_system_operation_context_.set_dest_origin_url(dest_origin_url); | 183 file_system_operation_context_.set_dest_origin_url(dest_origin_url); |
| 180 file_system_operation_context_.set_src_type(src_type); | 184 file_system_operation_context_.set_src_type(src_type); |
| 181 file_system_operation_context_.set_dest_type(dest_type); | 185 file_system_operation_context_.set_dest_type(dest_type); |
| 182 FileSystemFileUtilProxy::Move( | 186 FileSystemFileUtilProxy::Move( |
| 183 file_system_operation_context_, | 187 file_system_operation_context_, |
| 184 proxy_, virtual_path_0, virtual_path_1, | 188 proxy_, virtual_path_0, virtual_path_1, |
| 185 callback_factory_.NewCallback( | 189 callback_factory_.NewCallback( |
| 186 &FileSystemOperation::DidFinishFileOperation)); | 190 &FileSystemOperation::DidFinishFileOperation)); |
| 187 } | 191 } |
| 188 | 192 |
| 189 void FileSystemOperation::DirectoryExists(const FilePath& path) { | 193 void FileSystemOperation::DirectoryExists(const GURL& path) { |
| 190 #ifndef NDEBUG | 194 #ifndef NDEBUG |
| 191 DCHECK(kOperationNone == pending_operation_); | 195 DCHECK(kOperationNone == pending_operation_); |
| 192 pending_operation_ = kOperationDirectoryExists; | 196 pending_operation_ = kOperationDirectoryExists; |
| 193 #endif | 197 #endif |
| 194 | 198 |
| 195 FilePath virtual_path; | 199 FilePath virtual_path; |
| 196 GURL origin_url; | 200 GURL origin_url; |
| 197 FileSystemType type; | 201 FileSystemType type; |
| 198 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { | 202 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
| 199 delete this; | 203 delete this; |
| 200 return; | 204 return; |
| 201 } | 205 } |
| 202 file_system_operation_context_.set_src_origin_url(origin_url); | 206 file_system_operation_context_.set_src_origin_url(origin_url); |
| 203 file_system_operation_context_.set_src_type(type); | 207 file_system_operation_context_.set_src_type(type); |
| 204 FileSystemFileUtilProxy::GetFileInfo( | 208 FileSystemFileUtilProxy::GetFileInfo( |
| 205 file_system_operation_context_, | 209 file_system_operation_context_, |
| 206 proxy_, virtual_path, callback_factory_.NewCallback( | 210 proxy_, virtual_path, callback_factory_.NewCallback( |
| 207 &FileSystemOperation::DidDirectoryExists)); | 211 &FileSystemOperation::DidDirectoryExists)); |
| 208 } | 212 } |
| 209 | 213 |
| 210 void FileSystemOperation::FileExists(const FilePath& path) { | 214 void FileSystemOperation::FileExists(const GURL& path) { |
| 211 #ifndef NDEBUG | 215 #ifndef NDEBUG |
| 212 DCHECK(kOperationNone == pending_operation_); | 216 DCHECK(kOperationNone == pending_operation_); |
| 213 pending_operation_ = kOperationFileExists; | 217 pending_operation_ = kOperationFileExists; |
| 214 #endif | 218 #endif |
| 215 | 219 |
| 216 FilePath virtual_path; | 220 FilePath virtual_path; |
| 217 GURL origin_url; | 221 GURL origin_url; |
| 218 FileSystemType type; | 222 FileSystemType type; |
| 219 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { | 223 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
| 220 delete this; | 224 delete this; |
| 221 return; | 225 return; |
| 222 } | 226 } |
| 223 file_system_operation_context_.set_src_origin_url(origin_url); | 227 file_system_operation_context_.set_src_origin_url(origin_url); |
| 224 file_system_operation_context_.set_src_type(type); | 228 file_system_operation_context_.set_src_type(type); |
| 225 FileSystemFileUtilProxy::GetFileInfo( | 229 FileSystemFileUtilProxy::GetFileInfo( |
| 226 file_system_operation_context_, | 230 file_system_operation_context_, |
| 227 proxy_, virtual_path, callback_factory_.NewCallback( | 231 proxy_, virtual_path, callback_factory_.NewCallback( |
| 228 &FileSystemOperation::DidFileExists)); | 232 &FileSystemOperation::DidFileExists)); |
| 229 } | 233 } |
| 230 | 234 |
| 231 void FileSystemOperation::GetMetadata(const FilePath& path) { | 235 void FileSystemOperation::GetMetadata(const GURL& path) { |
| 232 #ifndef NDEBUG | 236 #ifndef NDEBUG |
| 233 DCHECK(kOperationNone == pending_operation_); | 237 DCHECK(kOperationNone == pending_operation_); |
| 234 pending_operation_ = kOperationGetMetadata; | 238 pending_operation_ = kOperationGetMetadata; |
| 235 #endif | 239 #endif |
| 236 | 240 |
| 237 FilePath virtual_path; | 241 FilePath virtual_path; |
| 238 GURL origin_url; | 242 GURL origin_url; |
| 239 FileSystemType type; | 243 FileSystemType type; |
| 240 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { | 244 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
| 241 delete this; | 245 delete this; |
| 242 return; | 246 return; |
| 243 } | 247 } |
| 244 file_system_operation_context_.set_src_origin_url(origin_url); | 248 file_system_operation_context_.set_src_origin_url(origin_url); |
| 245 file_system_operation_context_.set_src_type(type); | 249 file_system_operation_context_.set_src_type(type); |
| 246 FileSystemFileUtilProxy::GetFileInfo( | 250 FileSystemFileUtilProxy::GetFileInfo( |
| 247 file_system_operation_context_, | 251 file_system_operation_context_, |
| 248 proxy_, virtual_path, callback_factory_.NewCallback( | 252 proxy_, virtual_path, callback_factory_.NewCallback( |
| 249 &FileSystemOperation::DidGetMetadata)); | 253 &FileSystemOperation::DidGetMetadata)); |
| 250 } | 254 } |
| 251 | 255 |
| 252 void FileSystemOperation::ReadDirectory(const FilePath& path) { | 256 void FileSystemOperation::ReadDirectory(const GURL& path) { |
| 253 #ifndef NDEBUG | 257 #ifndef NDEBUG |
| 254 DCHECK(kOperationNone == pending_operation_); | 258 DCHECK(kOperationNone == pending_operation_); |
| 255 pending_operation_ = kOperationReadDirectory; | 259 pending_operation_ = kOperationReadDirectory; |
| 256 #endif | 260 #endif |
| 257 | 261 |
| 258 FilePath virtual_path; | 262 FilePath virtual_path; |
| 259 GURL origin_url; | 263 GURL origin_url; |
| 260 FileSystemType type; | 264 FileSystemType type; |
| 261 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { | 265 if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) { |
| 262 delete this; | 266 delete this; |
| 263 return; | 267 return; |
| 264 } | 268 } |
| 265 file_system_operation_context_.set_src_origin_url(origin_url); | 269 file_system_operation_context_.set_src_origin_url(origin_url); |
| 266 file_system_operation_context_.set_src_type(type); | 270 file_system_operation_context_.set_src_type(type); |
| 267 FileSystemFileUtilProxy::ReadDirectory( | 271 FileSystemFileUtilProxy::ReadDirectory( |
| 268 file_system_operation_context_, | 272 file_system_operation_context_, |
| 269 proxy_, virtual_path, callback_factory_.NewCallback( | 273 proxy_, virtual_path, callback_factory_.NewCallback( |
| 270 &FileSystemOperation::DidReadDirectory)); | 274 &FileSystemOperation::DidReadDirectory)); |
| 271 } | 275 } |
| 272 | 276 |
| 273 void FileSystemOperation::Remove(const FilePath& path, bool recursive) { | 277 void FileSystemOperation::Remove(const GURL& path, bool recursive) { |
| 274 #ifndef NDEBUG | 278 #ifndef NDEBUG |
| 275 DCHECK(kOperationNone == pending_operation_); | 279 DCHECK(kOperationNone == pending_operation_); |
| 276 pending_operation_ = kOperationRemove; | 280 pending_operation_ = kOperationRemove; |
| 277 #endif | 281 #endif |
| 278 | 282 |
| 279 FilePath virtual_path; | 283 FilePath virtual_path; |
| 280 GURL origin_url; | 284 GURL origin_url; |
| 281 FileSystemType type; | 285 FileSystemType type; |
| 282 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, | 286 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, |
| 283 &type, &virtual_path)) { | 287 &type, &virtual_path)) { |
| 284 delete this; | 288 delete this; |
| 285 return; | 289 return; |
| 286 } | 290 } |
| 287 file_system_operation_context_.set_src_origin_url(origin_url); | 291 file_system_operation_context_.set_src_origin_url(origin_url); |
| 288 file_system_operation_context_.set_src_type(type); | 292 file_system_operation_context_.set_src_type(type); |
| 289 FileSystemFileUtilProxy::Delete( | 293 FileSystemFileUtilProxy::Delete( |
| 290 file_system_operation_context_, | 294 file_system_operation_context_, |
| 291 proxy_, virtual_path, recursive, callback_factory_.NewCallback( | 295 proxy_, virtual_path, recursive, callback_factory_.NewCallback( |
| 292 &FileSystemOperation::DidFinishFileOperation)); | 296 &FileSystemOperation::DidFinishFileOperation)); |
| 293 } | 297 } |
| 294 | 298 |
| 295 void FileSystemOperation::Write( | 299 void FileSystemOperation::Write( |
| 296 scoped_refptr<net::URLRequestContext> url_request_context, | 300 scoped_refptr<net::URLRequestContext> url_request_context, |
| 297 const FilePath& path, | 301 const GURL& path, |
| 298 const GURL& blob_url, | 302 const GURL& blob_url, |
| 299 int64 offset) { | 303 int64 offset) { |
| 300 #ifndef NDEBUG | 304 #ifndef NDEBUG |
| 301 DCHECK(kOperationNone == pending_operation_); | 305 DCHECK(kOperationNone == pending_operation_); |
| 302 pending_operation_ = kOperationWrite; | 306 pending_operation_ = kOperationWrite; |
| 303 #endif | 307 #endif |
| 304 FilePath virtual_path; | 308 FilePath virtual_path; |
| 305 GURL origin_url; | 309 GURL origin_url; |
| 306 FileSystemType type; | 310 FileSystemType type; |
| 307 if (!VerifyFileSystemPathForWrite(path, true /* create */, &origin_url, | 311 if (!VerifyFileSystemPathForWrite(path, true /* create */, &origin_url, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 319 FileSystemFileUtilProxy::CreateOrOpen( | 323 FileSystemFileUtilProxy::CreateOrOpen( |
| 320 file_system_operation_context_, | 324 file_system_operation_context_, |
| 321 proxy_, | 325 proxy_, |
| 322 virtual_path, | 326 virtual_path, |
| 323 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | | 327 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | |
| 324 base::PLATFORM_FILE_ASYNC, | 328 base::PLATFORM_FILE_ASYNC, |
| 325 callback_factory_.NewCallback( | 329 callback_factory_.NewCallback( |
| 326 &FileSystemOperation::OnFileOpenedForWrite)); | 330 &FileSystemOperation::OnFileOpenedForWrite)); |
| 327 } | 331 } |
| 328 | 332 |
| 329 void FileSystemOperation::Truncate(const FilePath& path, int64 length) { | 333 void FileSystemOperation::Truncate(const GURL& path, int64 length) { |
| 330 #ifndef NDEBUG | 334 #ifndef NDEBUG |
| 331 DCHECK(kOperationNone == pending_operation_); | 335 DCHECK(kOperationNone == pending_operation_); |
| 332 pending_operation_ = kOperationTruncate; | 336 pending_operation_ = kOperationTruncate; |
| 333 #endif | 337 #endif |
| 334 FilePath virtual_path; | 338 FilePath virtual_path; |
| 335 GURL origin_url; | 339 GURL origin_url; |
| 336 FileSystemType type; | 340 FileSystemType type; |
| 337 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, | 341 if (!VerifyFileSystemPathForWrite(path, false /* create */, &origin_url, |
| 338 &type, &virtual_path)) { | 342 &type, &virtual_path)) { |
| 339 delete this; | 343 delete this; |
| 340 return; | 344 return; |
| 341 } | 345 } |
| 342 file_system_operation_context_.set_src_origin_url(origin_url); | 346 file_system_operation_context_.set_src_origin_url(origin_url); |
| 343 file_system_operation_context_.set_src_type(type); | 347 file_system_operation_context_.set_src_type(type); |
| 344 FileSystemFileUtilProxy::Truncate( | 348 FileSystemFileUtilProxy::Truncate( |
| 345 file_system_operation_context_, | 349 file_system_operation_context_, |
| 346 proxy_, virtual_path, length, callback_factory_.NewCallback( | 350 proxy_, virtual_path, length, callback_factory_.NewCallback( |
| 347 &FileSystemOperation::DidFinishFileOperation)); | 351 &FileSystemOperation::DidFinishFileOperation)); |
| 348 } | 352 } |
| 349 | 353 |
| 350 void FileSystemOperation::TouchFile(const FilePath& path, | 354 void FileSystemOperation::TouchFile(const GURL& path, |
| 351 const base::Time& last_access_time, | 355 const base::Time& last_access_time, |
| 352 const base::Time& last_modified_time) { | 356 const base::Time& last_modified_time) { |
| 353 #ifndef NDEBUG | 357 #ifndef NDEBUG |
| 354 DCHECK(kOperationNone == pending_operation_); | 358 DCHECK(kOperationNone == pending_operation_); |
| 355 pending_operation_ = kOperationTouchFile; | 359 pending_operation_ = kOperationTouchFile; |
| 356 #endif | 360 #endif |
| 357 | 361 |
| 358 FilePath virtual_path; | 362 FilePath virtual_path; |
| 359 GURL origin_url; | 363 GURL origin_url; |
| 360 FileSystemType type; | 364 FileSystemType type; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 // been cancelled, report it, and report that the cancel has succeeded. | 405 // been cancelled, report it, and report that the cancel has succeeded. |
| 402 DCHECK(!cancel_operation_.get()); | 406 DCHECK(!cancel_operation_.get()); |
| 403 cancel_operation_.swap(cancel_operation); | 407 cancel_operation_.swap(cancel_operation); |
| 404 } | 408 } |
| 405 } | 409 } |
| 406 | 410 |
| 407 void FileSystemOperation::DidGetRootPath( | 411 void FileSystemOperation::DidGetRootPath( |
| 408 bool success, | 412 bool success, |
| 409 const FilePath& path, const std::string& name) { | 413 const FilePath& path, const std::string& name) { |
| 410 DCHECK(success || path.empty()); | 414 DCHECK(success || path.empty()); |
| 411 FilePath result; | 415 GURL result; |
| 412 // We ignore the path, and return a URL instead. The point was just to verify | 416 // We ignore the path, and return a URL instead. The point was just to verify |
| 413 // that we could create/find the path. | 417 // that we could create/find the path. |
| 414 if (success) { | 418 if (success) { |
| 415 GURL root_url = GetFileSystemRootURI( | 419 result = GetFileSystemRootURI( |
| 416 file_system_operation_context_.src_origin_url(), | 420 file_system_operation_context_.src_origin_url(), |
| 417 file_system_operation_context_.src_type()); | 421 file_system_operation_context_.src_type()); |
| 418 result = FilePath().AppendASCII(root_url.spec()); | |
| 419 } | 422 } |
| 420 dispatcher_->DidOpenFileSystem(name, result); | 423 dispatcher_->DidOpenFileSystem(name, result); |
| 421 delete this; | 424 delete this; |
| 422 } | 425 } |
| 423 | 426 |
| 424 void FileSystemOperation::DidEnsureFileExistsExclusive( | 427 void FileSystemOperation::DidEnsureFileExistsExclusive( |
| 425 base::PlatformFileError rv, bool created) { | 428 base::PlatformFileError rv, bool created) { |
| 426 if (rv == base::PLATFORM_FILE_OK && !created) { | 429 if (rv == base::PLATFORM_FILE_OK && !created) { |
| 427 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); | 430 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); |
| 428 delete this; | 431 delete this; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 bool created) { | 533 bool created) { |
| 531 if (base::PLATFORM_FILE_OK != rv) { | 534 if (base::PLATFORM_FILE_OK != rv) { |
| 532 dispatcher_->DidFail(rv); | 535 dispatcher_->DidFail(rv); |
| 533 delete this; | 536 delete this; |
| 534 return; | 537 return; |
| 535 } | 538 } |
| 536 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); | 539 file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); |
| 537 } | 540 } |
| 538 | 541 |
| 539 bool FileSystemOperation::VerifyFileSystemPathForRead( | 542 bool FileSystemOperation::VerifyFileSystemPathForRead( |
| 540 const FilePath& path, GURL* origin_url, FileSystemType* type, | 543 const GURL& path, GURL* origin_url, FileSystemType* type, |
| 541 FilePath* virtual_path) { | 544 FilePath* virtual_path) { |
| 542 | 545 |
| 543 // If we have no context, we just allow any operations, for testing. | 546 // If we have no context, we just allow any operations, for testing. |
| 544 // TODO(ericu): Revisit this hack for security. | 547 // TODO(ericu): Revisit this hack for security. |
| 545 if (!file_system_context()) { | 548 if (!file_system_context()) { |
| 546 *virtual_path = path; | 549 #ifdef OS_WIN |
| 550 // On Windows, the path will look like /C:/foo/bar; we need to remove the |
| 551 // leading slash to make it valid. But if it's empty, we shouldn't do |
| 552 // anything. |
| 553 std::string temp = UnescapeURLComponent(path.path(), |
| 554 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); |
| 555 if (temp.size()) |
| 556 temp = temp.substr(1); |
| 557 *virtual_path = FilePath(UTF8ToWide(temp)).NormalizeWindowsPathSeparators(); |
| 558 #else |
| 559 *virtual_path = FilePath(path.path()); |
| 560 #endif |
| 547 *type = file_system_operation_context_.src_type(); | 561 *type = file_system_operation_context_.src_type(); |
| 562 *origin_url = file_system_operation_context_.src_origin_url(); |
| 548 return true; | 563 return true; |
| 549 } | 564 } |
| 550 | 565 |
| 551 // We may want do more checks, but for now it just checks if the given | 566 // We may want do more checks, but for now it just checks if the given |
| 552 // |path| is under the valid FileSystem root path for this host context. | 567 // URL is valid. |
| 553 if (!file_system_context()->path_manager()->CrackFileSystemPath( | 568 if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) { |
| 554 path, origin_url, type, virtual_path)) { | 569 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 570 return false; |
| 571 } |
| 572 if (!file_system_context()->path_manager()->IsAllowedFileSystemType( |
| 573 *origin_url, *type)) { |
| 555 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 574 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 556 return false; | 575 return false; |
| 557 } | 576 } |
| 558 | 577 |
| 559 return true; | 578 return true; |
| 560 } | 579 } |
| 561 | 580 |
| 562 bool FileSystemOperation::VerifyFileSystemPathForWrite( | 581 bool FileSystemOperation::VerifyFileSystemPathForWrite( |
| 563 const FilePath& path, bool create, GURL* origin_url, FileSystemType* type, | 582 const GURL& path, bool create, GURL* origin_url, FileSystemType* type, |
| 564 FilePath* virtual_path) { | 583 FilePath* virtual_path) { |
| 565 | 584 |
| 566 // If we have no context, we just allow any operations, for testing. | 585 // If we have no context, we just allow any operations, for testing. |
| 567 // TODO(ericu): Revisit this hack for security. | 586 // TODO(ericu): Revisit this hack for security. |
| 568 if (!file_system_context()) { | 587 if (!file_system_context()) { |
| 569 *virtual_path = path; | 588 #ifdef OS_WIN |
| 589 // On Windows, the path will look like /C:/foo/bar; we need to remove the |
| 590 // leading slash to make it valid. But if it's empty, we shouldn't do |
| 591 // anything. |
| 592 std::string temp = UnescapeURLComponent(path.path(), |
| 593 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); |
| 594 if (temp.size()) |
| 595 temp = temp.substr(1); |
| 596 *virtual_path = FilePath(UTF8ToWide(temp)).NormalizeWindowsPathSeparators(); |
| 597 #else |
| 598 *virtual_path = FilePath(path.path()); |
| 599 #endif |
| 570 *type = file_system_operation_context_.dest_type(); | 600 *type = file_system_operation_context_.dest_type(); |
| 601 *origin_url = file_system_operation_context_.dest_origin_url(); |
| 571 return true; | 602 return true; |
| 572 } | 603 } |
| 573 | 604 |
| 574 if (!file_system_context()->path_manager()->CrackFileSystemPath( | 605 if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) { |
| 575 path, origin_url, type, virtual_path)) { | 606 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 607 return false; |
| 608 } |
| 609 if (!file_system_context()->path_manager()->IsAllowedFileSystemType( |
| 610 *origin_url, *type)) { |
| 576 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 611 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 577 return false; | 612 return false; |
| 578 } | 613 } |
| 579 // Any write access is disallowed on the root path. | 614 // Any write access is disallowed on the root path. |
| 580 if (virtual_path->value().length() == 0 || | 615 if (virtual_path->value().length() == 0 || |
| 581 virtual_path->DirName().value() == virtual_path->value()) { | 616 virtual_path->DirName().value() == virtual_path->value()) { |
| 582 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 617 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 583 return false; | 618 return false; |
| 584 } | 619 } |
| 585 if (create && file_system_context()->path_manager()->IsRestrictedFileName( | 620 if (create && file_system_context()->path_manager()->IsRestrictedFileName( |
| 586 *type, virtual_path->BaseName())) { | 621 *type, virtual_path->BaseName())) { |
| 587 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); | 622 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY); |
| 588 return false; | 623 return false; |
| 589 } | 624 } |
| 590 // TODO(kinuko): the check must be moved to QuotaFileSystemFileUtil. | 625 // TODO(kinuko): the check must be moved to QuotaFileSystemFileUtil. |
| 591 if (!file_system_context()->IsStorageUnlimited(*origin_url)) { | 626 if (!file_system_context()->IsStorageUnlimited(*origin_url)) { |
| 592 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); | 627 dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); |
| 593 return false; | 628 return false; |
| 594 } | 629 } |
| 595 return true; | 630 return true; |
| 596 } | 631 } |
| 597 | 632 |
| 598 } // namespace fileapi | 633 } // namespace fileapi |
| OLD | NEW |