in frontend/app/DeliverableUploader/UploadService.ts [58:150]
async function ChunkedUploadFromEntry(
entry: FileEntry,
index: number,
uploadSlotId: string,
chunkSize: number,
updateCb: (updated: FileEntry, index: number) => void
) {
const uploadChunk = async (chunkIndex: number) => {
const lastByte =
(chunkIndex + 1) * chunkSize > entry.rawFile.size
? entry.rawFile.size
: (chunkIndex + 1) * chunkSize;
const blob = entry.rawFile.slice(chunkIndex * chunkSize, lastByte);
let localEntry = Object.assign([], entry);
let response: Response;
const targetUrl = `/deliverable-receiver/upload?uploadId=${uploadSlotId}&fileName=${entry.filename}`;
try {
const token = localStorage.getItem("pluto:access-token");
response = await fetch(targetUrl, {
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
Authorization: `Bearer ${token}`,
Range: `bytes=${chunkIndex * chunkSize}-${lastByte}/${
entry.rawFile.size
}`,
},
body: blob,
});
} catch (err) {
console.error("Upload failed: ", err);
localEntry.lastError = err.toString();
updateCb(localEntry, index);
throw "upload failed";
}
switch (response.status) {
case 413:
localEntry.lastError = "chunk size is too large";
updateCb(localEntry, index);
throw "upload failed";
case 500 | 400:
try {
const responseBody = await response.json();
if (responseBody.detail) {
localEntry.lastError = responseBody.detail;
} else {
localEntry.lastError = responseBody.toString();
}
updateCb(localEntry, index);
} catch (err) {
console.warn("could not parse error json: ", err);
localEntry.lastError = "server error, see browser console";
updateCb(localEntry, index);
}
throw "upload failed";
case 503:
localEntry.lastError = "server not responding, retrying...";
updateCb(localEntry, index);
return new Promise((resolve, reject) =>
window.setTimeout(() => {
uploadChunk(chunkIndex)
.then(resolve)
.catch((err) => reject(err));
}, 2000)
);
case 403:
localEntry.lastError = "permission denied";
updateCb(localEntry, index);
throw "upload failed";
case 200:
const responseBody = await response.json();
console.log(responseBody);
const fractionComplete =
((chunkIndex + 1) * chunkSize) / entry.rawFile.size;
localEntry.progress = Math.round(fractionComplete * 100.0);
updateCb(localEntry, index);
}
};
const chunksCount = Math.ceil(entry.rawFile.size / chunkSize);
console.log(
"chunked upload: there are ",
chunksCount,
" chunks for file of size ",
entry.rawFile.size
);
for (let i = 0; i < chunksCount; i++) {
console.log("uploading chunk ", i);
await uploadChunk(i);
}
}