diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts index 66c3bbf026..b40780d125 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts @@ -15,25 +15,17 @@ */ import archiver from 'archiver'; -import unzipper2, { Entry } from 'yauzl'; +import yauzl, { Entry } from 'yauzl'; import fs from 'fs-extra'; import platformPath from 'path'; import { Readable } from 'stream'; -// import unzipper, { Entry } from 'unzipper'; import { ReadTreeResponse, ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; +import { streamToBuffer } from './util'; -const streamToBuffer = async (stream: Readable): Promise => { - const buffers: Buffer[] = []; - return new Promise((resolve, reject) => { - stream.on('data', (data: Buffer) => buffers.push(data)); - stream.on('error', reject); - stream.on('end', () => resolve(Buffer.concat(buffers))); - }); -}; /** * Wraps a zip archive stream into a tree response reader. */ @@ -144,7 +136,7 @@ export class ZipArchiveResponse implements ReadTreeResponse { callback: (entry: Entry, content: Readable) => Promise, ): Promise { return new Promise((resolve, reject) => { - unzipper2.open(zip, { lazyEntries: true }, (err, zipfile) => { + yauzl.open(zip, { lazyEntries: true }, (err, zipfile) => { if (err) { reject(err); return; diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index 49c696467c..bfe02ac6c8 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -18,36 +18,18 @@ // containing any character except `/` one or more times, and ending with a `/` // e.g. Will match `dirA/` in `dirA/dirB/file.ext` const directoryNameRegex = /^[^\/]+\//; - +import { Readable } from 'stream'; // Removes the first segment of a forward-slash-separated path export function stripFirstDirectoryFromPath(path: string): string { return path.replace(directoryNameRegex, ''); } -// Some corrupted ZIP files cause the zlib inflater to hang indefinitely. -// This is a workaround to bail on stuck streams after 3 seconds. -// Related: https://github.com/ZJONSSON/node-unzipper/issues/213 -export async function streamToTimeoutPromise( - stream: NodeJS.ReadableStream, - options: { - timeoutMs: number; - eventName: string; - getError: (data: T) => Error; - }, -) { - let lastEntryTimeout: NodeJS.Timeout | undefined; - stream.on(options.eventName, (data: T) => { - clearTimeout(lastEntryTimeout); - - lastEntryTimeout = setTimeout(() => { - stream.emit('error', options.getError(data)); - }, options.timeoutMs); - }); - - await new Promise((resolve, reject) => { - stream.on('finish', resolve); +// Concats the data into a buffer. +export const streamToBuffer = async (stream: Readable): Promise => { + const buffers: Buffer[] = []; + return new Promise((resolve, reject) => { + stream.on('data', (data: Buffer) => buffers.push(data)); stream.on('error', reject); + stream.on('end', () => resolve(Buffer.concat(buffers))); }); - - clearTimeout(lastEntryTimeout); -} +};