From f2d9aa0872e6c733276987eae95e21fa53334014 Mon Sep 17 00:00:00 2001 From: NoahAndrews Date: Thu, 13 Apr 2023 18:36:59 -0500 Subject: [PATCH] Don't use the content-length HTTP header to check size of data content-length will differ from the actual size of the data if the HTTP response was compressed. --- .changeset/little-spies-double.md | 6 +++ .../builder-util-runtime/src/httpExecutor.ts | 41 ++++--------------- 2 files changed, 15 insertions(+), 32 deletions(-) create mode 100644 .changeset/little-spies-double.md diff --git a/.changeset/little-spies-double.md b/.changeset/little-spies-double.md new file mode 100644 index 00000000000..d103aea47ca --- /dev/null +++ b/.changeset/little-spies-double.md @@ -0,0 +1,6 @@ +--- +"builder-util-runtime": patch +"electron-updater": patch +--- + +Fix differential downloads when the server compresses the blockmap file HTTP response diff --git a/packages/builder-util-runtime/src/httpExecutor.ts b/packages/builder-util-runtime/src/httpExecutor.ts index e049703502e..e185b547b71 100644 --- a/packages/builder-util-runtime/src/httpExecutor.ts +++ b/packages/builder-util-runtime/src/httpExecutor.ts @@ -217,7 +217,7 @@ Please double check that your authentication token is correct. Due to security r async downloadToBuffer(url: URL, options: DownloadOptions): Promise { return await options.cancellationToken.createPromise((resolve, reject, onCancel) => { - let result: Buffer | null = null + const responseChunks: Buffer[] = [] const requestOptions = { headers: options.headers || undefined, // because PrivateGitHubProvider requires HttpExecutor.prepareRedirectUrlOptions logic, so, we need to redirect manually @@ -233,46 +233,23 @@ Please double check that your authentication token is correct. Due to security r onCancel, callback: error => { if (error == null) { - resolve(result!) + resolve(Buffer.concat(responseChunks)) } else { reject(error) } }, responseHandler: (response, callback) => { - const contentLength = safeGetHeader(response, "content-length") - let position = -1 - if (contentLength != null) { - const size = parseInt(contentLength, 10) - if (size > 0) { - if (size > 524288000) { - callback(new Error("Maximum allowed size is 500 MB")) - return - } - - result = Buffer.alloc(size) - position = 0 - } - } + let receivedLength = 0 response.on("data", (chunk: Buffer) => { - if (position !== -1) { - chunk.copy(result!, position) - position += chunk.length - } else if (result == null) { - result = chunk - } else { - if (result.length > 524288000) { - callback(new Error("Maximum allowed size is 500 MB")) - return - } - result = Buffer.concat([result, chunk]) + receivedLength += chunk.length + if (receivedLength > 524288000) { + callback(new Error("Maximum allowed size is 500 MB")) + return } + responseChunks.push(chunk) }) response.on("end", () => { - if (result != null && position !== -1 && position !== result.length) { - callback(new Error(`Received data length ${position} is not equal to expected ${result.length}`)) - } else { - callback(null) - } + callback(null) }) }, },