From a1df778d6fd9aedf16c546d75041190293710f97 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 14 Dec 2024 21:08:29 +1300 Subject: [PATCH] show if file transfer is being accepted, and add guard clauses for out of order packets --- src/components/pages/NodeFilesPage.vue | 41 ++++++++++++++++++++++++-- src/js/Connection.js | 30 +++++++++++++++++++ src/js/FileTransferrer.js | 7 +++-- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/components/pages/NodeFilesPage.vue b/src/components/pages/NodeFilesPage.vue index 89382f2..daba4fd 100644 --- a/src/components/pages/NodeFilesPage.vue +++ b/src/components/pages/NodeFilesPage.vue @@ -68,9 +68,22 @@ -
- Accept - Reject +
+
+ Accept + Reject +
+
+
+ + + + +
+
+ Accepting +
+
@@ -149,6 +162,11 @@ export default { } }, + data() { + return { + isAcceptingFileTransferIds: [], + }; + }, methods: { hasPublicKey: (nodeId) => NodeUtils.hasPublicKey(nodeId), getNodeLongName: (nodeId) => NodeUtils.getNodeLongName(nodeId), @@ -188,6 +206,20 @@ export default { setTimeout(() => URL.revokeObjectURL(objectUrl), 10000); }, + isAcceptingFileTransfer(fileTransferId) { + return this.isAcceptingFileTransferIds.includes(fileTransferId); + }, + setIsAcceptingFileTransfer(fileTransferId, isAcceptingFileTransfer) { + if(isAcceptingFileTransfer){ + // add to list of ids + this.isAcceptingFileTransferIds.push(fileTransferId); + } else { + // remove from list of ids + this.isAcceptingFileTransferIds = this.isAcceptingFileTransferIds.filter((existingFileTransferId) => { + return existingFileTransferId !== fileTransferId; + }); + } + }, async offerFileTransfer() { // do nothing if file is not selected @@ -207,9 +239,12 @@ export default { }, async acceptFileTransfer(fileTransfer) { try { + this.setIsAcceptingFileTransfer(fileTransfer.id, true); await FileTransferrer.acceptFileTransfer(fileTransfer); } catch(e) { DialogUtils.showErrorAlert(e); + } finally { + this.setIsAcceptingFileTransfer(fileTransfer.id, false); } }, async rejectFileTransfer(fileTransfer) { diff --git a/src/js/Connection.js b/src/js/Connection.js index 1819fc0..e769337 100644 --- a/src/js/Connection.js +++ b/src/js/Connection.js @@ -540,6 +540,12 @@ class Connection { return; } + // do nothing if file transfer not in offering state + if(fileTransfer.status !== FileTransferrer.STATUS_OFFERING){ + console.log(`[FileTransfer] ${fileTransfer.id} accepted, but no longer in offering state`); + return; + } + console.log(`[FileTransfer] ${fileTransfer.id} accepted`); // determine how many parts will be sent @@ -568,6 +574,12 @@ class Connection { return; } + // do nothing if file transfer not in offering state + if(fileTransfer.status !== FileTransferrer.STATUS_OFFERING){ + console.log(`[FileTransfer] ${fileTransfer.id} rejected, but no longer in offering state`); + return; + } + console.log(`[FileTransfer] ${fileTransfer.id} rejected`); // update file transfer status @@ -587,6 +599,12 @@ class Connection { return; } + // do nothing if file transfer in completed state + if(fileTransfer.status === FileTransferrer.STATUS_COMPLETED){ + console.log(`[FileTransfer] ${fileTransfer.id} cancelled, but already in completed state`); + return; + } + console.log(`[FileTransfer] ${fileTransfer.id} cancelled`); // remove cancelled file transfer if it was in offering state @@ -633,6 +651,12 @@ class Connection { return; } + // do nothing if file transfer not in accepted or receiving state + if(fileTransfer.status !== FileTransferrer.STATUS_ACCEPTED && fileTransfer.status !== FileTransferrer.STATUS_RECEIVING){ + console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}, but not in accepted or receiving state.`); + return; + } + console.log(`[FileTransfer] ${fileTransfer.id} received part ${filePart.partIndex + 1}/${filePart.totalParts}`); // cache received data @@ -673,6 +697,12 @@ class Connection { return; } + // do nothing if file transfer not in accepted or sending state + if(fileTransfer.status !== FileTransferrer.STATUS_ACCEPTED && fileTransfer.status !== FileTransferrer.STATUS_SENDING){ + console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}, but not in accepted or sending state.`); + return; + } + console.log(`[FileTransfer] ${fileTransfer.id} requested file parts ${requestFileParts.partIndexes}.`); // send parts diff --git a/src/js/FileTransferrer.js b/src/js/FileTransferrer.js index c2d14d8..fc760a8 100644 --- a/src/js/FileTransferrer.js +++ b/src/js/FileTransferrer.js @@ -8,7 +8,6 @@ class FileTransferrer { static DIRECTION_OUTGOING = "outgoing"; static STATUS_OFFERING = "offering"; - static STATUS_OFFERED = "offered"; static STATUS_ACCEPTED = "accepted"; static STATUS_REJECTED = "rejected"; static STATUS_CANCELLED = "cancelled"; @@ -54,7 +53,6 @@ class FileTransferrer { this.log(`offerFileTransfer attempt ${attempt}`); await FileTransferAPI.sendFileTransferRequest(to, fileTransferId, fileName, fileSize); this.log(`offerFileTransfer attempt ${attempt} success`); - fileTransfer.status = this.STATUS_OFFERED; return; } catch(e) { console.log(e); @@ -105,7 +103,7 @@ class FileTransferrer { for(var attempt = 1; attempt <= this.MAX_PACKET_ATTEMPTS; attempt++){ try { this.log(`rejectFileTransfer attempt ${attempt}`); - await FileTransferAPI.acceptFileTransfer(fileTransfer.from, fileTransfer.id); + await FileTransferAPI.rejectFileTransfer(fileTransfer.from, fileTransfer.id); fileTransfer.status = this.STATUS_ACCEPTED; return; } catch(e) { @@ -154,6 +152,9 @@ class FileTransferrer { const end = start + partSize; const partData = fileTransfer.data.slice(start, end); + // update status + fileTransfer.status = FileTransferrer.STATUS_SENDING; + // send part to remote node for(var attempt = 1; attempt <= this.MAX_PACKET_ATTEMPTS; attempt++){ try {