aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/code/src/installation/download_file.ts36
1 files changed, 17 insertions, 19 deletions
diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts
index 71700ec8a..b31d2a736 100644
--- a/editors/code/src/installation/download_file.ts
+++ b/editors/code/src/installation/download_file.ts
@@ -1,8 +1,12 @@
1import fetch from "node-fetch"; 1import fetch from "node-fetch";
2import * as fs from "fs"; 2import * as fs from "fs";
3import * as stream from "stream";
4import * as util from "util";
3import { strict as assert } from "assert"; 5import { strict as assert } from "assert";
4import { NestedError } from "ts-nested-error"; 6import { NestedError } from "ts-nested-error";
5 7
8const pipeline = util.promisify(stream.pipeline);
9
6class DownloadFileError extends NestedError {} 10class DownloadFileError extends NestedError {}
7 11
8/** 12/**
@@ -29,25 +33,19 @@ export async function downloadFile(
29 const totalBytes = Number(res.headers.get('content-length')); 33 const totalBytes = Number(res.headers.get('content-length'));
30 assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol"); 34 assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol");
31 35
32 let readBytes = 0;
33
34 console.log("Downloading file of", totalBytes, "bytes size from", url, "to", destFilePath); 36 console.log("Downloading file of", totalBytes, "bytes size from", url, "to", destFilePath);
35 37
36 // Here reject() may be called 2 times. As per ECMAScript standard, 2-d call is ignored 38 let readBytes = 0;
37 // https://tc39.es/ecma262/#sec-promise-reject-functions 39 res.body.on("data", (chunk: Buffer) => {
38 40 readBytes += chunk.length;
39 return new Promise<void>((resolve, reject) => res.body 41 onProgress(readBytes, totalBytes);
40 .on("data", (chunk: Buffer) => { 42 });
41 readBytes += chunk.length; 43
42 onProgress(readBytes, totalBytes); 44 const destFileStream = fs.createWriteStream(destFilePath, { mode: destFilePermissions });
43 }) 45
44 .on("error", err => reject( 46 await pipeline(res.body, destFileStream).catch(DownloadFileError.rethrow("Piping file error"));
45 new DownloadFileError(`Read-stream error, read bytes: ${readBytes}`, err) 47 return new Promise<void>(resolve => {
46 )) 48 destFileStream.on("close", resolve); // details on workaround: https://github.com/rust-analyzer/rust-analyzer/pull/3092#discussion_r378191131
47 .pipe(fs.createWriteStream(destFilePath, { mode: destFilePermissions })) 49 destFileStream.destroy();
48 .on("error", err => reject( 50 });
49 new DownloadFileError(`Write-stream error, read bytes: ${readBytes}`, err)
50 ))
51 .on("close", resolve)
52 );
53} 51}