ssn/src/cdn/funcs/saveResponse.ts

53 lines
1.6 KiB
TypeScript

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<Promise<void>> = [];
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);
});
});
}