代码之家  ›  专栏  ›  技术社区  ›  andymel

如何防止StreamableFile/createReadStream在NestJS中泄漏路径

  •  0
  • andymel  · 技术社区  · 2 年前

    我试图做什么
    我想使用NestJs将文件内容流式传输到http客户端。
    目前,我使用 StreamableFile 所述对象 in the NestJs docs

    问题是
    找不到服务器上的文件时

    • 我的解决方案发送了一个 400 Bad Request 而不是404
    • 更重要的是 错误包含服务器端文件的路径

    不幸的是,我还不知道如何在将错误发送到客户端之前捕获它。

    NestJs控制器中的端点

    @Get('coordinates/:processId')
    @Header('Content-Type', 'application/json')
    public async getCoordinates(
        @Param('processId') processId: string
    ): Promise<StreamableFile> {
        
        return this.getFileContentStream(
            join(
                this.getProcessingDir(processId),
                "coordinates.json"
            )
        );
    }
    

    还有我的 getFileContentStream 做必要事情的方法

    private getFileContentStream(path: string): Promise<StreamableFile> {
    
        return new Promise((resolve, reject) => {
            
            // throw new BadRequestException("test");
    
            const errorHandler = (err: Error) => {
                const myErr = new Error(`Error reading data`, { cause: err });
                Logger.error(getErrorMessageWithCausedByParts(myErr));
                reject(myErr);
            }
        
            const stream = createReadStream(path);
                
            stream.on('error', errorHandler);
            // stream.prependListener('error', errorHandler)
            //stream.on('end', () => Logger.verbose(`End of streaming '${path}'`));
    
            resolve(new StreamableFile(stream))
        })
    }
    

    这是错误日志

    [Nest] 262768  - 16.08.2023, 21:12:16   ERROR Error: Error reading data
        at ReadStream.errorHandler (...\src\lib\controllers\fem-results.controller.ts:40:31)
        at ReadStream.emit (node:events:525:35)
        at emitErrorNT (node:internal/streams/destroy:151:8)
        at emitErrorCloseNT (node:internal/streams/destroy:116:3)
        at processTicksAndRejections (node:internal/process/task_queues:82:21)
    [caused by] Error: ENOENT: no such file or directory, open '...\processing\04921742-c563-4a2d-96d1-ef8786daf014\info.json'
    [Nest] 262768  - 16.08.2023, 21:12:16   DEBUG GET /api/calc/fem-results/info/04921742-c563-4a2d-96d1-ef8786daf014 400 193 - 239.489 ms
    [Nest] 262768  - 16.08.2023, 21:12:16   ERROR [ExpressAdapter] ENOENT: no such file or directory, open '...\processing\04921742-c563-4a2d-96d1-ef8786daf014\info.json'
    

    最后一行中的错误也会发送到客户端。文件的路径是绝对的。我只是把它缩短了。。。

    我读过 “您可以监听此事件以防止抛出错误的默认行为” 在里面 this SO answer 而且 this 看起来我可以过滤它,但要么我做错了,要么当流与StreamableFile一起使用时不是这样。

    我不知道ReadStream何时尝试访问该文件,但我想只有在解析了promise之后才能访问,因此拒绝可能不起作用。但我相信有一些方法可以防止错误文本泄露到客户端。

    我必须使用某种管道来过滤掉这个错误吗?或者你知道另一种方法吗?

    0 回复  |  直到 2 年前