Skip to content

Commit 3e29d47

Browse files
authored
fix: use pipeline instead of pipe (#1906)
* fix: use pipeline instead of pipe * refactor: get string without tmp file
1 parent b2e59c7 commit 3e29d47

4 files changed

Lines changed: 18 additions & 48 deletions

File tree

src/services/file/file.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { MaybeUser, MinimalMember } from '../../types';
66
import { CachingService } from '../caching/service';
77
import type { LocalFileConfiguration, S3FileConfiguration } from './interfaces/configuration';
88
import type { FileRepository } from './interfaces/fileRepository';
9-
import { createSanitizedFile, sanitizeHtml } from './sanitize';
9+
import { sanitizeDocument, sanitizeHtml } from './sanitize';
1010
import {
1111
CopyFileInvalidPathError,
1212
CopyFolderInvalidPathError,
@@ -98,7 +98,7 @@ class FileService {
9898
async sanitizeFile({ file, mimetype }: { file: Readable; mimetype?: string }): Promise<Readable> {
9999
// sanitize content of html
100100
if (mimetype === 'text/html') {
101-
return await createSanitizedFile(file, sanitizeHtml);
101+
return await sanitizeDocument(file, sanitizeHtml);
102102
}
103103

104104
return file;

src/services/file/repositories/s3.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import fs from 'fs';
1111
import { StatusCodes } from 'http-status-codes';
1212
import fetch from 'node-fetch';
1313
import path from 'path';
14+
import { pipeline } from 'stream/promises';
1415

1516
import type { FastifyBaseLogger } from 'fastify';
1617

@@ -194,12 +195,7 @@ export class S3FileRepository implements FileRepository {
194195
}
195196

196197
const fileStream = fs.createWriteStream(filepath);
197-
await new Promise<void>((resolve, reject) => {
198-
res.body.pipe(fileStream);
199-
res.body.on('error', reject);
200-
fileStream.on('finish', resolve);
201-
});
202-
fileStream.end();
198+
await pipeline(res.body, fileStream);
203199

204200
// create and return read stream (similar to local file service)
205201
const file = fs.createReadStream(filepath);

src/services/file/sanitize.ts

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,23 @@
1-
import { createWriteStream } from 'fs';
2-
import { readFile, unlink } from 'fs/promises';
3-
import path from 'path';
41
import sanitize from 'sanitize-html';
52
import { Readable } from 'stream';
6-
7-
import { TMP_FOLDER } from '../../utils/config';
8-
import { randomHexOf4 } from '../utils';
3+
import { text } from 'stream/consumers';
94

105
export function sanitizeHtml(content: string): string {
116
return sanitize(content);
127
}
138

14-
export function createSanitizedFile(
9+
export async function sanitizeDocument(
1510
file: Readable,
1611
sanitizeFn: (content: string) => string,
1712
): Promise<Readable> {
18-
return new Promise((done, rejects) => {
19-
// create tmp file to read
20-
const tmpFile = path.join(TMP_FOLDER, `${Date.now().toString()}_${randomHexOf4()}`);
21-
file.pipe(createWriteStream(tmpFile));
22-
23-
file.on('error', function () {
24-
rejects(new Error('An error happened while piping the file to sanitize'));
25-
});
26-
27-
file.on('close', async function () {
28-
const content = await readFile(tmpFile, {
29-
encoding: 'utf8',
30-
flag: 'r',
31-
});
32-
33-
const readable = Readable.from(sanitizeFn(content));
34-
35-
// delete tmp file
36-
unlink(tmpFile).catch((e) => console.error(e));
37-
38-
// return sanitized readable
39-
done(readable);
40-
});
41-
});
13+
try {
14+
const content = await text(file);
15+
const readable = Readable.from(sanitizeFn(content));
16+
17+
// return sanitized readable
18+
return readable;
19+
} catch (e) {
20+
console.error(e);
21+
throw new Error('An error happened while creating a sanitized version of the file');
22+
}
4223
}

src/services/thumbnail/thumbnail.service.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'path';
22
import sharp from 'sharp';
33
import { Readable } from 'stream';
4+
import { pipeline as streamPipeline } from 'stream/promises';
45
import { injectable } from 'tsyringe';
56

67
import { BaseLogger } from '../../logger';
@@ -40,15 +41,7 @@ export class ThumbnailService {
4041
Object.entries(ThumbnailSizeFormat).map(async ([sizeName, width]) => {
4142
// create thumbnail from image stream
4243
const pipeline = sharp().resize({ width }).toFormat(THUMBNAIL_FORMAT);
43-
file.pipe(pipeline);
44-
45-
await new Promise((resolve, reject) =>
46-
pipeline
47-
.on('finish', () => {
48-
resolve(true);
49-
})
50-
.on('error', reject),
51-
);
44+
await streamPipeline(file, pipeline);
5245

5346
return {
5447
file: pipeline,

0 commit comments

Comments
 (0)