2017-10-11 21:43:21 +00:00
|
|
|
// @flow
|
2017-10-28 22:16:34 +00:00
|
|
|
import * as electron from 'electron';
|
2017-10-11 21:43:21 +00:00
|
|
|
import mimes from 'mime-types';
|
|
|
|
import fs from 'fs';
|
|
|
|
import path from 'path';
|
|
|
|
import type {RequestBodyParameter} from '../models/request';
|
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
export const DEFAULT_BOUNDARY = 'X-INSOMNIA-BOUNDARY';
|
2017-10-11 21:43:21 +00:00
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
export async function buildMultipart (params: Array<RequestBodyParameter>) {
|
|
|
|
return new Promise(async (resolve: Function, reject: Function) => {
|
|
|
|
const filePath = path.join(electron.remote.app.getPath('temp'), Math.random() + '.body');
|
|
|
|
const writeStream = fs.createWriteStream(filePath);
|
|
|
|
const lineBreak = '\r\n';
|
|
|
|
let totalSize = 0;
|
|
|
|
|
2017-11-10 17:30:09 +00:00
|
|
|
function addFile (path: string): Promise<void> {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
let size;
|
|
|
|
try {
|
|
|
|
size = fs.statSync(path).size;
|
|
|
|
} catch (err) {
|
|
|
|
reject(err);
|
|
|
|
}
|
2017-10-28 22:16:34 +00:00
|
|
|
const stream = fs.createReadStream(path);
|
|
|
|
stream.once('end', () => {
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
stream.pipe(writeStream, {end: false});
|
|
|
|
totalSize += size;
|
|
|
|
});
|
2017-10-11 21:43:21 +00:00
|
|
|
}
|
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
const addString = (v: string) => {
|
|
|
|
const buffer = Buffer.from(v);
|
|
|
|
writeStream.write(buffer);
|
|
|
|
totalSize += buffer.length;
|
|
|
|
};
|
2017-10-11 21:43:21 +00:00
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
for (const param of params) {
|
|
|
|
const noName = !param.name;
|
|
|
|
const noValue = !(param.value || param.fileName);
|
|
|
|
|
|
|
|
if (noName && noValue) {
|
|
|
|
continue;
|
|
|
|
}
|
2017-10-11 21:43:21 +00:00
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
addString(`--${DEFAULT_BOUNDARY}`);
|
|
|
|
addString(lineBreak);
|
|
|
|
|
|
|
|
if (param.type === 'file' && param.fileName) {
|
|
|
|
const name = param.name || '';
|
|
|
|
const fileName = param.fileName;
|
|
|
|
const contentType = mimes.lookup(fileName) || 'application/octet-stream';
|
|
|
|
addString(
|
|
|
|
'Content-Disposition: form-data; ' +
|
|
|
|
`name="${name.replace(/"/g, '\\"')}"; ` +
|
|
|
|
`filename="${path.basename(fileName).replace(/"/g, '\\"')}"`
|
|
|
|
);
|
|
|
|
addString(lineBreak);
|
|
|
|
addString(`Content-Type: ${contentType}`);
|
|
|
|
addString(lineBreak);
|
|
|
|
addString(lineBreak);
|
2017-11-10 17:30:09 +00:00
|
|
|
try {
|
|
|
|
await addFile(fileName);
|
|
|
|
} catch (err) {
|
|
|
|
return reject(err);
|
|
|
|
}
|
2017-10-28 22:16:34 +00:00
|
|
|
} else {
|
|
|
|
const name = param.name || '';
|
|
|
|
const value = param.value || '';
|
|
|
|
addString(`Content-Disposition: form-data; name="${name}"`);
|
|
|
|
addString(lineBreak);
|
|
|
|
addString(lineBreak);
|
|
|
|
addString(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
addString(lineBreak);
|
2017-10-11 21:43:21 +00:00
|
|
|
}
|
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
addString(`--${DEFAULT_BOUNDARY}--`);
|
|
|
|
addString(lineBreak);
|
|
|
|
|
|
|
|
writeStream.on('error', err => {
|
|
|
|
reject(err);
|
|
|
|
});
|
2017-10-11 21:43:21 +00:00
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
writeStream.on('close', () => {
|
|
|
|
resolve({boundary: DEFAULT_BOUNDARY, filePath, contentLength: totalSize});
|
|
|
|
});
|
2017-10-11 21:43:21 +00:00
|
|
|
|
2017-10-28 22:16:34 +00:00
|
|
|
// We're done here. End the stream and tell FS to save/close the file.
|
|
|
|
writeStream.end();
|
|
|
|
});
|
2017-10-11 21:43:21 +00:00
|
|
|
}
|