rittenhop-ghost/versions/5.94.2/node_modules/stripe/lib/multipart.js

97 lines
2.7 KiB
JavaScript
Raw Normal View History

'use strict';
const utils = require('./utils');
const {StripeError} = require('./Error');
class StreamProcessingError extends StripeError {}
// Method for formatting HTTP body for the multipart/form-data specification
// Mostly taken from Fermata.js
// https://github.com/natevw/fermata/blob/5d9732a33d776ce925013a265935facd1626cc88/fermata.js#L315-L343
const multipartDataGenerator = (method, data, headers) => {
const segno = (
Math.round(Math.random() * 1e16) + Math.round(Math.random() * 1e16)
).toString();
headers['Content-Type'] = `multipart/form-data; boundary=${segno}`;
let buffer = Buffer.alloc(0);
function push(l) {
const prevBuffer = buffer;
const newBuffer = l instanceof Buffer ? l : Buffer.from(l);
buffer = Buffer.alloc(prevBuffer.length + newBuffer.length + 2);
prevBuffer.copy(buffer);
newBuffer.copy(buffer, prevBuffer.length);
buffer.write('\r\n', buffer.length - 2);
}
function q(s) {
return `"${s.replace(/"|"/g, '%22').replace(/\r\n|\r|\n/g, ' ')}"`;
}
const flattenedData = utils.flattenAndStringify(data);
for (const k in flattenedData) {
const v = flattenedData[k];
push(`--${segno}`);
if (v.hasOwnProperty('data')) {
push(
`Content-Disposition: form-data; name=${q(k)}; filename=${q(
v.name || 'blob'
)}`
);
push(`Content-Type: ${v.type || 'application/octet-stream'}`);
push('');
push(v.data);
} else {
push(`Content-Disposition: form-data; name=${q(k)}`);
push('');
push(v);
}
}
push(`--${segno}--`);
return buffer;
};
const streamProcessor = (method, data, headers, callback) => {
const bufferArray = [];
data.file.data
.on('data', (line) => {
bufferArray.push(line);
})
.once('end', () => {
const bufferData = Object.assign({}, data);
bufferData.file.data = Buffer.concat(bufferArray);
const buffer = multipartDataGenerator(method, bufferData, headers);
callback(null, buffer);
})
.on('error', (err) => {
callback(
new StreamProcessingError({
message:
'An error occurred while attempting to process the file for upload.',
detail: err,
}),
null
);
});
};
const multipartRequestDataProcessor = (method, data, headers, callback) => {
data = data || {};
if (method !== 'POST') {
return callback(null, utils.stringifyRequestData(data));
}
const isStream = utils.checkForStream(data);
if (isStream) {
return streamProcessor(method, data, headers, callback);
}
const buffer = multipartDataGenerator(method, data, headers);
return callback(null, buffer);
};
module.exports.multipartRequestDataProcessor = multipartRequestDataProcessor;