问题描述
在第一个服务中:我正在使用 GridFS 上传文件并将它们存储在 MongoDB 上,然后公开REST 端点下载文件。
// Controller
@Get(':md5')
async getFile(@Param('md5') md5: string,@Res() res) {
// const file = await this.fileService.findInfo(md5)
const filestream = await this.fileService.readStream(md5)
if(!filestream){
throw new HttpException('An error occurred while retrieving file',HttpStatus.EXPECTATION_Failed)
}
res.header('Content-Type','application/octet-stream');
return filestream.pipe(res)
}
// Service
async readStream(md5: string): Promise<GridFSBucketReadStream> {
const fileMetadata = await this.getobjectIdFromMd5(md5);
const id = fileMetadata.id;
const db = await this.getDatabase();
const fileModel = new MongoGridFS(db,'fs');
return await fileModel.readFileStream(id);
}
public async getobjectIdFromMd5(md5: string): Promise<{ id: string,fileName: string }> {
const db = await this.getDatabase();
const document = await db.collection('fs.files').findOne({ 'md5': md5 });
if (document === null) {
return null;
}
return { id: document._id,fileName: document.filename };
}
private async getBucket() {
const db = await this.getDatabase();
var bucket = new GridFSBucket(db);
return bucket;
}
private async getDatabase() {
const client: MongoClient = await MongoClient.connect(this.uri,{ useUnifiedTopology: true });
const db = client.db(this.dbname);
return db;
}
在第二个服务中:我使用以下代码下载文件并计算文件的哈希以确保文件未被篡改。 >
public async downloadFile(fileNAme,filehash) {
const file: string = `./temp-files/${fileName}`;
axios({
method: 'get',url: `http://localhost:8000/api/download/${filehash}`,responseType: 'stream',}).then((response) => {
response.data.pipe(fs.createWriteStream(file));
this.matchHashes(file,filehash);
});
}
private matchHashes(filePath: string,serverHash: string) {
const crypto = require('crypto');
const fileData = fs.readFileSync(filePath);
const computedHash = crypto.createHash('md5').update(fileData).digest('hex');
console.log('Server Hash: ' + serverHash);
console.log('Hash after download from mongo: ' + computedHash)
if (computedHash !== serverHash) {
throw new Error('files hash mismatch');
}
}
问题:我将计算出的 md5 与 MongoDB GridFS md5 哈希生成的 md5 匹配,有时某些文件的哈希匹配某些文件的某些文件此匹配失败,行为是随机的。 我什至尝试在上传文件之前以及执行 GET 操作和从 mongo 获取文件之后计算 sha256 而不是 md5,看到了相同的行为。
控制台日志:
Server Hash: d28e404f87957bfdc7548b579f14c082
Hash after download from mongo: d41d8cd98f00b204e9800998ecf8427e
(node:6615) UnhandledPromiseRejectionWarning: Error: files hash mismatch
...
当我尝试使用 MongoDB 内置驱动程序计算 md5 哈希值时,为其提供存储文件的 ObjectId:
db.adminCommand({ filemd5: ObjectId("60cca45292a3424b34f02b55"),root: "fs" })
它返回:
{
"numChunks" : 0,"md5" : "d41d8cd98f00b204e9800998ecf8427e","ok" : 1.0
}
这相当于使用 GET REST 调用下载文件后计算出的哈希值。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)