1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/filesystem/RemoveTask.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,204 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "RemoveTask.h" 1.11 + 1.12 +#include "DOMError.h" 1.13 +#include "mozilla/dom/FileSystemBase.h" 1.14 +#include "mozilla/dom/FileSystemUtils.h" 1.15 +#include "mozilla/dom/Promise.h" 1.16 +#include "nsIDOMFile.h" 1.17 +#include "nsIFile.h" 1.18 +#include "nsStringGlue.h" 1.19 + 1.20 +namespace mozilla { 1.21 +namespace dom { 1.22 + 1.23 +RemoveTask::RemoveTask(FileSystemBase* aFileSystem, 1.24 + const nsAString& aDirPath, 1.25 + nsIDOMFile* aTargetFile, 1.26 + const nsAString& aTargetPath, 1.27 + bool aRecursive) 1.28 + : FileSystemTaskBase(aFileSystem) 1.29 + , mDirRealPath(aDirPath) 1.30 + , mTargetFile(aTargetFile) 1.31 + , mTargetRealPath(aTargetPath) 1.32 + , mRecursive(aRecursive) 1.33 + , mReturnValue(false) 1.34 +{ 1.35 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.36 + MOZ_ASSERT(aFileSystem); 1.37 + nsCOMPtr<nsIGlobalObject> globalObject = 1.38 + do_QueryInterface(aFileSystem->GetWindow()); 1.39 + if (!globalObject) { 1.40 + return; 1.41 + } 1.42 + mPromise = new Promise(globalObject); 1.43 +} 1.44 + 1.45 +RemoveTask::RemoveTask(FileSystemBase* aFileSystem, 1.46 + const FileSystemRemoveParams& aParam, 1.47 + FileSystemRequestParent* aParent) 1.48 + : FileSystemTaskBase(aFileSystem, aParam, aParent) 1.49 + , mRecursive(false) 1.50 + , mReturnValue(false) 1.51 +{ 1.52 + MOZ_ASSERT(FileSystemUtils::IsParentProcess(), 1.53 + "Only call from parent process!"); 1.54 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.55 + MOZ_ASSERT(aFileSystem); 1.56 + 1.57 + mDirRealPath = aParam.directory(); 1.58 + 1.59 + mRecursive = aParam.recursive(); 1.60 + 1.61 + const FileSystemPathOrFileValue& target = aParam.target(); 1.62 + 1.63 + if (target.type() == FileSystemPathOrFileValue::TnsString) { 1.64 + mTargetRealPath = target; 1.65 + return; 1.66 + } 1.67 + 1.68 + BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(target)); 1.69 + nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob(); 1.70 + mTargetFile = do_QueryInterface(blob); 1.71 + MOZ_ASSERT(mTargetFile, "mTargetFile should not be null."); 1.72 +} 1.73 + 1.74 +RemoveTask::~RemoveTask() 1.75 +{ 1.76 + MOZ_ASSERT(!mPromise || NS_IsMainThread(), 1.77 + "mPromise should be released on main thread!"); 1.78 +} 1.79 + 1.80 +already_AddRefed<Promise> 1.81 +RemoveTask::GetPromise() 1.82 +{ 1.83 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.84 + return nsRefPtr<Promise>(mPromise).forget(); 1.85 +} 1.86 + 1.87 +FileSystemParams 1.88 +RemoveTask::GetRequestParams(const nsString& aFileSystem) const 1.89 +{ 1.90 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.91 + FileSystemRemoveParams param; 1.92 + param.filesystem() = aFileSystem; 1.93 + param.directory() = mDirRealPath; 1.94 + param.recursive() = mRecursive; 1.95 + if (mTargetFile) { 1.96 + BlobChild* actor 1.97 + = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mTargetFile); 1.98 + if (actor) { 1.99 + param.target() = actor; 1.100 + } 1.101 + } else { 1.102 + param.target() = mTargetRealPath; 1.103 + } 1.104 + return param; 1.105 +} 1.106 + 1.107 +FileSystemResponseValue 1.108 +RemoveTask::GetSuccessRequestResult() const 1.109 +{ 1.110 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.111 + return FileSystemBooleanResponse(mReturnValue); 1.112 +} 1.113 + 1.114 +void 1.115 +RemoveTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue) 1.116 +{ 1.117 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.118 + FileSystemBooleanResponse r = aValue; 1.119 + mReturnValue = r.success(); 1.120 +} 1.121 + 1.122 +nsresult 1.123 +RemoveTask::Work() 1.124 +{ 1.125 + MOZ_ASSERT(FileSystemUtils::IsParentProcess(), 1.126 + "Only call from parent process!"); 1.127 + MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!"); 1.128 + 1.129 + if (mFileSystem->IsShutdown()) { 1.130 + return NS_ERROR_FAILURE; 1.131 + } 1.132 + 1.133 + // Get the DOM path if a DOMFile is passed as the target. 1.134 + if (mTargetFile) { 1.135 + if (!mFileSystem->GetRealPath(mTargetFile, mTargetRealPath)) { 1.136 + return NS_ERROR_DOM_SECURITY_ERR; 1.137 + } 1.138 + if (!FileSystemUtils::IsDescendantPath(mDirRealPath, mTargetRealPath)) { 1.139 + return NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR; 1.140 + } 1.141 + } 1.142 + 1.143 + nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath); 1.144 + if (!file) { 1.145 + return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR; 1.146 + } 1.147 + 1.148 + bool exists = false; 1.149 + nsresult rv = file->Exists(&exists); 1.150 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.151 + return rv; 1.152 + } 1.153 + 1.154 + if (!exists) { 1.155 + mReturnValue = false; 1.156 + return NS_OK; 1.157 + } 1.158 + 1.159 + bool isFile = false; 1.160 + rv = file->IsFile(&isFile); 1.161 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.162 + return rv; 1.163 + } 1.164 + 1.165 + if (isFile && !mFileSystem->IsSafeFile(file)) { 1.166 + return NS_ERROR_DOM_SECURITY_ERR; 1.167 + } 1.168 + 1.169 + rv = file->Remove(mRecursive); 1.170 + if (NS_WARN_IF(NS_FAILED(rv))) { 1.171 + return rv; 1.172 + } 1.173 + 1.174 + mReturnValue = true; 1.175 + 1.176 + return NS_OK; 1.177 +} 1.178 + 1.179 +void 1.180 +RemoveTask::HandlerCallback() 1.181 +{ 1.182 + MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); 1.183 + if (mFileSystem->IsShutdown()) { 1.184 + mPromise = nullptr; 1.185 + return; 1.186 + } 1.187 + 1.188 + if (HasError()) { 1.189 + nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(), 1.190 + mErrorValue); 1.191 + mPromise->MaybeReject(domError); 1.192 + mPromise = nullptr; 1.193 + return; 1.194 + } 1.195 + 1.196 + mPromise->MaybeResolve(mReturnValue); 1.197 + mPromise = nullptr; 1.198 +} 1.199 + 1.200 +void 1.201 +RemoveTask::GetPermissionAccessType(nsCString& aAccess) const 1.202 +{ 1.203 + aAccess.AssignLiteral("write"); 1.204 +} 1.205 + 1.206 +} // namespace dom 1.207 +} // namespace mozilla