使用 multer 将带有 request() 的 Decipher / Cipher 对象(二进制数据)发送到 API

Send Decipher / Cipher Object (binary data) with request() to API with multer

我们在 Node.js 中有两个 API。第一个充当主要集线器,而另一个用于发送电子邮件。

目前我有一些文件被加密存储在第一个API的文件系统中。使用以下函数解密文件:

decryptFile: function (filePath, callback) {
                var fileName = path.basename(filePath);
                var encryptedFilePath = path.dirname(filePath) + '/' + this.encryptText(fileName);
                // input file
                var fileDecipher = encryptionKeys.crypto.createDecipher(encryptionKeys.algorithm, encryptionKeys.password);
                var r = fs.createReadStream(encryptedFilePath);
                // decrypt content
                r.on("error", function (err) {
                    if (err) {
                        callback(err);
                    }
                });
                return callback(null, r.pipe(fileDecipher));

        }

发送我们使用的文件:

utils.files.decryptFile(fullPath, function (err, decryptedFile) {

requestOptions = {
            url: pushAPIURL + 'email/send',
            method: "POST",
            formData: {
               attachments: [decryptedFile]
            },
            headers: {
                authorization: global.PUSHToken
            }
            // json: body
        };
        return request(requestOptions);
});

因此我们收到:

Error: Part terminated early due to unexpected end of multipart data

在邮件中 API

知道请求中可能遗漏了什么吗?

谢谢

好吧,经过一番挖掘,我忘记了这里的问题。我在 form-data 的 GitHub 问题中发布了我的问题的解决方案:https://github.com/form-data/form-data/issues/409#issuecomment-432202588

以下是原始答案,以防以上内容不再可用:

So the solution to this was thanks to: https://github.com/form-data/form-data/issues/356#issue-234978025

It seems indeed related to the missing known length of the stream + seemingly some other metadata fields that are missing. On the file decryption function, I added the counting of the stream length for each chunk:

            let file, length = 0;
            // decrypt content
            r.on("error", function (err) {
                if (err) {
                    callback(err);
                }
            });
            r.on("data", function (chunk) {
                // console.log("data");
                length += chunk.length;
            });
            r.on("end", function () {
                // console.log("end");
                return callback(null, file, fileName, length);
            });
            file = r.pipe(fileDecipher);

Then, on the file that is sending the request we add the following

utils.files.decryptFile(fullPath, function (err, decryptedFile, filename, >length) {
            decryptedFile.httpVersion = "1.0";
            decryptedFile.name = filename;
            decryptedFile.headers = {'content-length': length};
            requestOptions = {
            url: pushAPIURL + 'email/send',
            method: "POST",
            formData: {
               attachments: [decryptedFile]
            },
            headers: {
                authorization: global.PUSHToken
            }
        };
        return request(requestOptions); 
    });