1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "fs/FileSystemRequestHandler.h"
9 #include "FileSystemEntryMetadataArray.h"
10 #include "fs/FileSystemConstants.h"
11 #include "mozilla/ResultVariant.h"
12 #include "mozilla/StaticPrefs_dom.h"
13 #include "mozilla/dom/BlobImpl.h"
14 #include "mozilla/dom/File.h"
15 #include "mozilla/dom/FileSystemAccessHandleChild.h"
16 #include "mozilla/dom/FileSystemDirectoryHandle.h"
17 #include "mozilla/dom/FileSystemFileHandle.h"
18 #include "mozilla/dom/FileSystemHandle.h"
19 #include "mozilla/dom/FileSystemHelpers.h"
20 #include "mozilla/dom/FileSystemLog.h"
21 #include "mozilla/dom/FileSystemManager.h"
22 #include "mozilla/dom/FileSystemManagerChild.h"
23 #include "mozilla/dom/FileSystemSyncAccessHandle.h"
24 #include "mozilla/dom/FileSystemWritableFileStream.h"
25 #include "mozilla/dom/FileSystemWritableFileStreamChild.h"
26 #include "mozilla/dom/IPCBlobUtils.h"
27 #include "mozilla/dom/Promise.h"
28 #include "mozilla/dom/WorkerCommon.h"
29 #include "mozilla/dom/WorkerRef.h"
30 #include "mozilla/dom/fs/IPCRejectReporter.h"
31 #include "mozilla/dom/quota/QuotaCommon.h"
32 #include "mozilla/dom/quota/ResultExtensions.h"
33 #include "mozilla/ipc/RandomAccessStreamUtils.h"
35 namespace mozilla::dom::fs
{
37 using mozilla::ipc::RejectCallback
;
41 void HandleFailedStatus(nsresult aError
, const RefPtr
<Promise
>& aPromise
) {
43 case NS_ERROR_FILE_ACCESS_DENIED
:
44 aPromise
->MaybeRejectWithNotAllowedError("Permission denied");
46 case NS_ERROR_FILE_NOT_FOUND
:
48 case NS_ERROR_DOM_NOT_FOUND_ERR
:
49 aPromise
->MaybeRejectWithNotFoundError("Entry not found");
51 case NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR
:
52 aPromise
->MaybeRejectWithInvalidModificationError("Disallowed by system");
54 case NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
:
55 aPromise
->MaybeRejectWithNoModificationAllowedError(
56 "No modification allowed");
58 case NS_ERROR_DOM_TYPE_MISMATCH_ERR
:
59 aPromise
->MaybeRejectWithTypeMismatchError("Wrong type");
61 case NS_ERROR_DOM_INVALID_MODIFICATION_ERR
:
62 aPromise
->MaybeRejectWithInvalidModificationError("Invalid modification");
65 if (NS_FAILED(aError
)) {
66 aPromise
->MaybeRejectWithUnknownError("Unknown failure");
68 aPromise
->MaybeResolveWithUndefined();
74 bool MakeResolution(nsIGlobalObject
* aGlobal
,
75 FileSystemGetEntriesResponse
&& aResponse
,
76 const bool& /* aResult */,
77 RefPtr
<FileSystemEntryMetadataArray
>& aSink
) {
78 // TODO: Add page size to FileSystemConstants, preallocate and handle overflow
79 const auto& listing
= aResponse
.get_FileSystemDirectoryListing();
81 for (const auto& it
: listing
.files()) {
82 aSink
->AppendElement(it
);
85 for (const auto& it
: listing
.directories()) {
86 aSink
->AppendElement(it
);
92 RefPtr
<FileSystemDirectoryHandle
> MakeResolution(
93 nsIGlobalObject
* aGlobal
, FileSystemGetHandleResponse
&& aResponse
,
94 const RefPtr
<FileSystemDirectoryHandle
>& /* aResult */,
95 RefPtr
<FileSystemManager
>& aManager
) {
96 RefPtr
<FileSystemDirectoryHandle
> result
= new FileSystemDirectoryHandle(
98 FileSystemEntryMetadata(aResponse
.get_EntryId(), kRootName
,
99 /* directory */ true));
103 RefPtr
<FileSystemDirectoryHandle
> MakeResolution(
104 nsIGlobalObject
* aGlobal
, FileSystemGetHandleResponse
&& aResponse
,
105 const RefPtr
<FileSystemDirectoryHandle
>& /* aResult */, const Name
& aName
,
106 RefPtr
<FileSystemManager
>& aManager
) {
107 RefPtr
<FileSystemDirectoryHandle
> result
= new FileSystemDirectoryHandle(
109 FileSystemEntryMetadata(aResponse
.get_EntryId(), aName
,
110 /* directory */ true));
115 RefPtr
<FileSystemFileHandle
> MakeResolution(
116 nsIGlobalObject
* aGlobal
, FileSystemGetHandleResponse
&& aResponse
,
117 const RefPtr
<FileSystemFileHandle
>& /* aResult */, const Name
& aName
,
118 RefPtr
<FileSystemManager
>& aManager
) {
119 RefPtr
<FileSystemFileHandle
> result
= new FileSystemFileHandle(
121 FileSystemEntryMetadata(aResponse
.get_EntryId(), aName
,
122 /* directory */ false));
126 RefPtr
<FileSystemSyncAccessHandle
> MakeResolution(
127 nsIGlobalObject
* aGlobal
, FileSystemGetAccessHandleResponse
&& aResponse
,
128 const RefPtr
<FileSystemSyncAccessHandle
>& /* aReturns */,
129 const FileSystemEntryMetadata
& aMetadata
,
130 RefPtr
<FileSystemManager
>& aManager
) {
131 auto& properties
= aResponse
.get_FileSystemAccessHandleProperties();
134 RefPtr
<FileSystemSyncAccessHandle
> result
,
135 FileSystemSyncAccessHandle::Create(
136 aGlobal
, aManager
, std::move(properties
.streamParams()),
137 std::move(properties
.accessHandleChildEndpoint()),
138 std::move(properties
.accessHandleControlChildEndpoint()), aMetadata
),
144 RefPtr
<FileSystemWritableFileStream
> MakeResolution(
145 nsIGlobalObject
* aGlobal
,
146 FileSystemGetWritableFileStreamResponse
&& aResponse
,
147 const RefPtr
<FileSystemWritableFileStream
>& /* aReturns */,
148 const FileSystemEntryMetadata
& aMetadata
,
149 RefPtr
<FileSystemManager
>& aManager
) {
150 auto& properties
= aResponse
.get_FileSystemWritableFileStreamProperties();
152 auto* const actor
= static_cast<FileSystemWritableFileStreamChild
*>(
153 properties
.writableFileStream().AsChild().get());
155 QM_TRY_UNWRAP(RefPtr
<FileSystemWritableFileStream
> result
,
156 FileSystemWritableFileStream::Create(
157 aGlobal
, aManager
, std::move(properties
.streamParams()),
164 RefPtr
<File
> MakeResolution(nsIGlobalObject
* aGlobal
,
165 FileSystemGetFileResponse
&& aResponse
,
166 const RefPtr
<File
>& /* aResult */,
168 RefPtr
<FileSystemManager
>& aManager
) {
169 auto& fileProperties
= aResponse
.get_FileSystemFileProperties();
171 RefPtr
<BlobImpl
> blobImpl
= IPCBlobUtils::Deserialize(fileProperties
.file());
172 MOZ_ASSERT(blobImpl
);
173 RefPtr
<File
> result
= File::Create(aGlobal
, blobImpl
);
177 template <class TResponse
, class... Args
>
178 void ResolveCallback(
179 TResponse
&& aResponse
,
180 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
182 MOZ_ASSERT(aPromise
);
183 QM_TRY(OkIf(Promise::PromiseState::Pending
== aPromise
->State()), QM_VOID
);
185 if (TResponse::Tnsresult
== aResponse
.type()) {
186 HandleFailedStatus(aResponse
.get_nsresult(), aPromise
);
190 auto resolution
= MakeResolution(aPromise
->GetParentObject(),
191 std::forward
<TResponse
>(aResponse
),
192 std::forward
<Args
>(args
)...);
194 aPromise
->MaybeRejectWithUnknownError("Could not complete request");
198 aPromise
->MaybeResolve(resolution
);
202 void ResolveCallback(
203 FileSystemRemoveEntryResponse
&& aResponse
,
204 RefPtr
<Promise
> aPromise
) { // NOLINT(performance-unnecessary-value-param)
205 MOZ_ASSERT(aPromise
);
206 QM_TRY(OkIf(Promise::PromiseState::Pending
== aPromise
->State()), QM_VOID
);
208 if (FileSystemRemoveEntryResponse::Tvoid_t
== aResponse
.type()) {
209 aPromise
->MaybeResolveWithUndefined();
213 MOZ_ASSERT(FileSystemRemoveEntryResponse::Tnsresult
== aResponse
.type());
214 HandleFailedStatus(aResponse
.get_nsresult(), aPromise
);
218 void ResolveCallback(
219 FileSystemMoveEntryResponse
&& aResponse
,
220 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
221 FileSystemEntryMetadata
* const& aEntry
, const Name
& aName
) {
222 MOZ_ASSERT(aPromise
);
223 QM_TRY(OkIf(Promise::PromiseState::Pending
== aPromise
->State()), QM_VOID
);
225 if (FileSystemMoveEntryResponse::TEntryId
== aResponse
.type()) {
227 aEntry
->entryId() = std::move(aResponse
.get_EntryId());
228 aEntry
->entryName() = aName
;
231 aPromise
->MaybeResolveWithUndefined();
234 MOZ_ASSERT(FileSystemMoveEntryResponse::Tnsresult
== aResponse
.type());
235 const auto& status
= aResponse
.get_nsresult();
236 MOZ_ASSERT(NS_FAILED(status
));
237 HandleFailedStatus(status
, aPromise
);
241 void ResolveCallback(FileSystemResolveResponse
&& aResponse
,
242 // NOLINTNEXTLINE(performance-unnecessary-value-param)
243 RefPtr
<Promise
> aPromise
) {
244 MOZ_ASSERT(aPromise
);
245 QM_TRY(OkIf(Promise::PromiseState::Pending
== aPromise
->State()), QM_VOID
);
247 if (FileSystemResolveResponse::Tnsresult
== aResponse
.type()) {
248 HandleFailedStatus(aResponse
.get_nsresult(), aPromise
);
252 auto& maybePath
= aResponse
.get_MaybeFileSystemPath();
253 if (maybePath
.isSome()) {
254 aPromise
->MaybeResolve(maybePath
.value().path());
258 // Spec says if there is no parent/child relationship, return null
259 aPromise
->MaybeResolve(JS::NullHandleValue
);
262 template <class TResponse
, class TReturns
, class... Args
,
263 std::enable_if_t
<std::is_same
<TReturns
, void>::value
, bool> = true>
264 mozilla::ipc::ResolveCallback
<TResponse
> SelectResolveCallback(
265 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
267 using TOverload
= void (*)(TResponse
&&, RefPtr
<Promise
>, Args
...);
268 return static_cast<std::function
<void(TResponse
&&)>>(
269 // NOLINTNEXTLINE(modernize-avoid-bind)
270 std::bind(static_cast<TOverload
>(ResolveCallback
), std::placeholders::_1
,
271 aPromise
, std::forward
<Args
>(args
)...));
274 template <class TResponse
, class TReturns
, class... Args
,
275 std::enable_if_t
<!std::is_same
<TReturns
, void>::value
, bool> = true>
276 mozilla::ipc::ResolveCallback
<TResponse
> SelectResolveCallback(
277 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
280 void (*)(TResponse
&&, RefPtr
<Promise
>, const TReturns
&, Args
...);
281 return static_cast<std::function
<void(TResponse
&&)>>(
282 // NOLINTNEXTLINE(modernize-avoid-bind)
283 std::bind(static_cast<TOverload
>(ResolveCallback
), std::placeholders::_1
,
284 aPromise
, TReturns(), std::forward
<Args
>(args
)...));
288 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
289 mozilla::ipc::ResponseRejectReason aReason
) {
290 IPCRejectReporter(aReason
);
291 QM_TRY(OkIf(Promise::PromiseState::Pending
== aPromise
->State()), QM_VOID
);
292 aPromise
->MaybeRejectWithUndefined();
295 mozilla::ipc::RejectCallback
GetRejectCallback(
296 RefPtr
<Promise
> aPromise
) { // NOLINT(performance-unnecessary-value-param)
297 return static_cast<mozilla::ipc::RejectCallback
>(
298 // NOLINTNEXTLINE(modernize-avoid-bind)
299 std::bind(RejectCallback
, aPromise
, std::placeholders::_1
));
302 struct BeginRequestFailureCallback
{
303 explicit BeginRequestFailureCallback(RefPtr
<Promise
> aPromise
)
304 : mPromise(std::move(aPromise
)) {}
306 void operator()(nsresult aRv
) const {
307 if (aRv
== NS_ERROR_DOM_SECURITY_ERR
) {
308 mPromise
->MaybeRejectWithSecurityError(
309 "Security error when calling GetDirectory");
312 mPromise
->MaybeRejectWithUnknownError("Could not create actor");
315 RefPtr
<Promise
> mPromise
;
320 void FileSystemRequestHandler::GetRootHandle(
321 RefPtr
<FileSystemManager
>
322 aManager
, // NOLINT(performance-unnecessary-value-param)
323 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
324 ErrorResult
& aError
) {
325 MOZ_ASSERT(aManager
);
326 MOZ_ASSERT(aPromise
);
327 LOG(("GetRootHandle"));
329 if (aManager
->IsShutdown()) {
330 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
334 aManager
->BeginRequest(
335 [onResolve
= SelectResolveCallback
<FileSystemGetHandleResponse
,
336 RefPtr
<FileSystemDirectoryHandle
>>(
338 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
339 actor
->SendGetRootHandle(std::move(onResolve
), std::move(onReject
));
341 BeginRequestFailureCallback(aPromise
));
344 void FileSystemRequestHandler::GetDirectoryHandle(
345 RefPtr
<FileSystemManager
>& aManager
,
346 const FileSystemChildMetadata
& aDirectory
, bool aCreate
,
347 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
348 ErrorResult
& aError
) {
349 MOZ_ASSERT(aManager
);
350 MOZ_ASSERT(!aDirectory
.parentId().IsEmpty());
351 MOZ_ASSERT(aPromise
);
352 LOG(("GetDirectoryHandle"));
354 if (aManager
->IsShutdown()) {
355 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
359 if (!IsValidName(aDirectory
.childName())) {
360 aPromise
->MaybeRejectWithTypeError("Invalid directory name");
364 aManager
->BeginRequest(
365 [request
= FileSystemGetHandleRequest(aDirectory
, aCreate
),
366 onResolve
= SelectResolveCallback
<FileSystemGetHandleResponse
,
367 RefPtr
<FileSystemDirectoryHandle
>>(
368 aPromise
, aDirectory
.childName(), aManager
),
369 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
370 actor
->SendGetDirectoryHandle(request
, std::move(onResolve
),
371 std::move(onReject
));
373 BeginRequestFailureCallback(aPromise
));
376 void FileSystemRequestHandler::GetFileHandle(
377 RefPtr
<FileSystemManager
>& aManager
, const FileSystemChildMetadata
& aFile
,
379 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
380 ErrorResult
& aError
) {
381 MOZ_ASSERT(aManager
);
382 MOZ_ASSERT(!aFile
.parentId().IsEmpty());
383 MOZ_ASSERT(aPromise
);
384 LOG(("GetFileHandle"));
386 if (aManager
->IsShutdown()) {
387 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
391 if (!IsValidName(aFile
.childName())) {
392 aPromise
->MaybeRejectWithTypeError("Invalid filename");
396 aManager
->BeginRequest(
397 [request
= FileSystemGetHandleRequest(aFile
, aCreate
),
398 onResolve
= SelectResolveCallback
<FileSystemGetHandleResponse
,
399 RefPtr
<FileSystemFileHandle
>>(
400 aPromise
, aFile
.childName(), aManager
),
401 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
402 actor
->SendGetFileHandle(request
, std::move(onResolve
),
403 std::move(onReject
));
405 BeginRequestFailureCallback(aPromise
));
408 void FileSystemRequestHandler::GetAccessHandle(
409 RefPtr
<FileSystemManager
>& aManager
, const FileSystemEntryMetadata
& aFile
,
410 const RefPtr
<Promise
>& aPromise
, ErrorResult
& aError
) {
411 MOZ_ASSERT(aManager
);
412 MOZ_ASSERT(aPromise
);
413 LOG(("GetAccessHandle %s", NS_ConvertUTF16toUTF8(aFile
.entryName()).get()));
415 if (aManager
->IsShutdown()) {
416 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
420 aManager
->BeginRequest(
421 [request
= FileSystemGetAccessHandleRequest(aFile
.entryId()),
422 onResolve
= SelectResolveCallback
<FileSystemGetAccessHandleResponse
,
423 RefPtr
<FileSystemSyncAccessHandle
>>(
424 aPromise
, aFile
, aManager
),
425 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
426 actor
->SendGetAccessHandle(request
, std::move(onResolve
),
427 std::move(onReject
));
429 BeginRequestFailureCallback(aPromise
));
432 void FileSystemRequestHandler::GetWritable(RefPtr
<FileSystemManager
>& aManager
,
433 const FileSystemEntryMetadata
& aFile
,
435 const RefPtr
<Promise
>& aPromise
,
436 ErrorResult
& aError
) {
437 MOZ_ASSERT(aManager
);
438 MOZ_ASSERT(aPromise
);
439 LOG(("GetWritable %s keep %d", NS_ConvertUTF16toUTF8(aFile
.entryName()).get(),
442 // XXX This should be removed once bug 1798513 is fixed.
443 if (!StaticPrefs::dom_fs_writable_file_stream_enabled()) {
444 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
448 if (aManager
->IsShutdown()) {
449 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
453 aManager
->BeginRequest(
454 [request
= FileSystemGetWritableRequest(aFile
.entryId(), aKeepData
),
456 SelectResolveCallback
<FileSystemGetWritableFileStreamResponse
,
457 RefPtr
<FileSystemWritableFileStream
>>(
458 aPromise
, aFile
, aManager
),
459 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
460 actor
->SendGetWritable(request
, std::move(onResolve
),
461 std::move(onReject
));
463 [promise
= aPromise
](const auto&) {
464 promise
->MaybeRejectWithUnknownError("Could not create actor");
468 void FileSystemRequestHandler::GetFile(
469 RefPtr
<FileSystemManager
>& aManager
, const FileSystemEntryMetadata
& aFile
,
470 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
471 ErrorResult
& aError
) {
472 MOZ_ASSERT(aManager
);
473 MOZ_ASSERT(!aFile
.entryId().IsEmpty());
474 MOZ_ASSERT(aPromise
);
475 LOG(("GetFile %s", NS_ConvertUTF16toUTF8(aFile
.entryName()).get()));
477 if (aManager
->IsShutdown()) {
478 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
482 aManager
->BeginRequest(
483 [request
= FileSystemGetFileRequest(aFile
.entryId()),
485 SelectResolveCallback
<FileSystemGetFileResponse
, RefPtr
<File
>>(
486 aPromise
, aFile
.entryName(), aManager
),
487 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
488 actor
->SendGetFile(request
, std::move(onResolve
), std::move(onReject
));
490 BeginRequestFailureCallback(aPromise
));
493 void FileSystemRequestHandler::GetEntries(
494 RefPtr
<FileSystemManager
>& aManager
, const EntryId
& aDirectory
,
496 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
497 RefPtr
<FileSystemEntryMetadataArray
>& aSink
, ErrorResult
& aError
) {
498 MOZ_ASSERT(aManager
);
499 MOZ_ASSERT(!aDirectory
.IsEmpty());
500 MOZ_ASSERT(aPromise
);
501 LOG(("GetEntries, page %u", aPage
));
503 if (aManager
->IsShutdown()) {
504 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
508 aManager
->BeginRequest(
509 [request
= FileSystemGetEntriesRequest(aDirectory
, aPage
),
510 onResolve
= SelectResolveCallback
<FileSystemGetEntriesResponse
, bool>(
512 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
513 actor
->SendGetEntries(request
, std::move(onResolve
),
514 std::move(onReject
));
516 BeginRequestFailureCallback(aPromise
));
519 void FileSystemRequestHandler::RemoveEntry(
520 RefPtr
<FileSystemManager
>& aManager
, const FileSystemChildMetadata
& aEntry
,
522 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
523 ErrorResult
& aError
) {
524 MOZ_ASSERT(aManager
);
525 MOZ_ASSERT(!aEntry
.parentId().IsEmpty());
526 MOZ_ASSERT(aPromise
);
527 LOG(("RemoveEntry"));
529 if (aManager
->IsShutdown()) {
530 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
534 if (!IsValidName(aEntry
.childName())) {
535 aPromise
->MaybeRejectWithTypeError("Invalid name");
539 aManager
->BeginRequest(
540 [request
= FileSystemRemoveEntryRequest(aEntry
, aRecursive
),
542 SelectResolveCallback
<FileSystemRemoveEntryResponse
, void>(aPromise
),
543 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
544 actor
->SendRemoveEntry(request
, std::move(onResolve
),
545 std::move(onReject
));
547 BeginRequestFailureCallback(aPromise
));
550 void FileSystemRequestHandler::MoveEntry(
551 RefPtr
<FileSystemManager
>& aManager
, FileSystemHandle
* aHandle
,
552 FileSystemEntryMetadata
* const aEntry
,
553 const FileSystemChildMetadata
& aNewEntry
,
554 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
555 ErrorResult
& aError
) {
557 MOZ_ASSERT(!aEntry
->entryId().IsEmpty());
558 MOZ_ASSERT(aPromise
);
561 if (aManager
->IsShutdown()) {
562 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
566 // reject invalid names: empty, path separators, current & parent directories
567 if (!IsValidName(aNewEntry
.childName())) {
568 aPromise
->MaybeRejectWithTypeError("Invalid name");
572 aManager
->BeginRequest(
573 [request
= FileSystemMoveEntryRequest(*aEntry
, aNewEntry
),
574 onResolve
= SelectResolveCallback
<FileSystemMoveEntryResponse
, void>(
575 aPromise
, aEntry
, aNewEntry
.childName()),
576 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
577 actor
->SendMoveEntry(request
, std::move(onResolve
),
578 std::move(onReject
));
580 BeginRequestFailureCallback(aPromise
));
583 void FileSystemRequestHandler::RenameEntry(
584 RefPtr
<FileSystemManager
>& aManager
, FileSystemHandle
* aHandle
,
585 FileSystemEntryMetadata
* const aEntry
, const Name
& aName
,
586 RefPtr
<Promise
> aPromise
, // NOLINT(performance-unnecessary-value-param)
587 ErrorResult
& aError
) {
589 MOZ_ASSERT(!aEntry
->entryId().IsEmpty());
590 MOZ_ASSERT(aPromise
);
591 LOG(("RenameEntry"));
593 if (aManager
->IsShutdown()) {
594 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
598 // reject invalid names: empty, path separators, current & parent directories
599 if (!IsValidName(aName
)) {
600 aPromise
->MaybeRejectWithTypeError("Invalid name");
604 aManager
->BeginRequest(
605 [request
= FileSystemRenameEntryRequest(*aEntry
, aName
),
606 onResolve
= SelectResolveCallback
<FileSystemMoveEntryResponse
, void>(
607 aPromise
, aEntry
, aName
),
608 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
609 actor
->SendRenameEntry(request
, std::move(onResolve
),
610 std::move(onReject
));
612 BeginRequestFailureCallback(aPromise
));
615 void FileSystemRequestHandler::Resolve(
616 RefPtr
<FileSystemManager
>& aManager
,
617 // NOLINTNEXTLINE(performance-unnecessary-value-param)
618 const FileSystemEntryPair
& aEndpoints
, RefPtr
<Promise
> aPromise
,
619 ErrorResult
& aError
) {
620 MOZ_ASSERT(aManager
);
621 MOZ_ASSERT(!aEndpoints
.parentId().IsEmpty());
622 MOZ_ASSERT(!aEndpoints
.childId().IsEmpty());
623 MOZ_ASSERT(aPromise
);
626 if (aManager
->IsShutdown()) {
627 aError
.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN
);
631 aManager
->BeginRequest(
632 [request
= FileSystemResolveRequest(aEndpoints
),
634 SelectResolveCallback
<FileSystemResolveResponse
, void>(aPromise
),
635 onReject
= GetRejectCallback(aPromise
)](const auto& actor
) mutable {
636 actor
->SendResolve(request
, std::move(onResolve
), std::move(onReject
));
638 BeginRequestFailureCallback(aPromise
));
641 } // namespace mozilla::dom::fs