import * as fs from 'fs'; import * as http from 'http'; export default function saveResponse( filePath: string, resolve: (fileName: string) => void, reject: (reason: string) => void, response: http.IncomingMessage, ) { //Check that file exists (200 HTTP status code) if (response.statusCode !== 200) { return reject(`Expected status code 200 but received ${response.statusCode}.`); } //Remember file size const headerLength = Number(response.headers['content-length']); const writeStream = fs.createWriteStream(filePath); //If we receive a part of the response, write it to disk let totalLength = 0; const chunkPromises: Array> = []; response.on('data', (chunk: Buffer) => { totalLength += chunk.length; //Exit early if we received too much data if (totalLength > headerLength) { return reject(`Expected length ${headerLength} but received at least ${totalLength}.`); } //Write chunk to disk chunkPromises.push(new Promise((writeResolve) => { writeStream.write(chunk, () => { writeResolve(); }); })); }); //If we finished reading response, check for correctness, then return it response.on('end', () => { //Check that length is correct if (totalLength !== headerLength) { return reject(`Expected length ${headerLength} but received ${totalLength}.`); } //wait until everything is written to disk, then return file name //TODO: need to automatically delete file once it is no longer used //TODO: need to provide methods to seek through file Promise.all(chunkPromises).then(() => { resolve(filePath); }); }); }