fix: multipart/form-data body interpolation (#3142)

* feat: updates

* feat: updates

* feat: updates

* feat: updates
This commit is contained in:
lohit
2024-09-23 15:54:54 +05:30
committed by GitHub
parent eb33504f19
commit ed20eccc25
13 changed files with 165 additions and 47 deletions

View File

@@ -1,5 +1,6 @@
const { interpolate } = require('@usebruno/common');
const { each, forOwn, cloneDeep, find } = require('lodash');
const FormData = require('form-data');
const getContentType = (headers = {}) => {
let contentType = '';
@@ -78,6 +79,14 @@ const interpolateVars = (request, envVars = {}, runtimeVariables = {}, processEn
request.data = JSON.parse(parsed);
} catch (err) {}
}
} else if (contentType === 'multipart/form-data') {
if (typeof request.data === 'object' && !(request?.data instanceof FormData)) {
try {
let parsed = JSON.stringify(request.data);
parsed = _interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {}
}
} else {
request.data = _interpolate(request.data);
}

View File

@@ -120,16 +120,10 @@ const prepareRequest = (request, collectionRoot) => {
}
if (request.body.mode === 'multipartForm') {
axiosRequest.headers['content-type'] = 'multipart/form-data';
const params = {};
const enabledParams = filter(request.body.multipartForm, (p) => p.enabled);
each(enabledParams, (p) => {
if (p.type === 'file') {
params[p.name] = p.value.map((path) => fs.createReadStream(path));
} else {
params[p.name] = p.value;
}
});
axiosRequest.headers['content-type'] = 'multipart/form-data';
each(enabledParams, (p) => (params[p.name] = p.value));
axiosRequest.data = params;
}

View File

@@ -19,6 +19,7 @@ const { makeAxiosInstance } = require('../utils/axios-instance');
const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-helper');
const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../utils/proxy-util');
const path = require('path');
const { createFormData } = require('../utils/common');
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
const onConsoleLog = (type, args) => {
@@ -45,21 +46,6 @@ const runSingleRequest = async function (
const scriptingConfig = get(brunoConfig, 'scripts', {});
scriptingConfig.runtime = runtime;
// make axios work in node using form data
// reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427
if (request.headers && request.headers['content-type'] === 'multipart/form-data') {
const form = new FormData();
forOwn(request.data, (value, key) => {
if (value instanceof Array) {
each(value, (v) => form.append(key, v));
} else {
form.append(key, value);
}
});
extend(request.headers, form.getHeaders());
request.data = form;
}
// run pre request script
const requestScriptFile = compact([
get(collectionRoot, 'request.script.req'),
@@ -195,6 +181,14 @@ const runSingleRequest = async function (
request.data = qs.stringify(request.data);
}
if (request?.headers?.['content-type'] === 'multipart/form-data') {
if (!(request?.data instanceof FormData)) {
let form = createFormData(request.data, collectionPath);
request.data = form;
extend(request.headers, form.getHeaders());
}
}
let response, responseTime;
try {
// run request

View File

@@ -1,3 +1,8 @@
const fs = require('fs');
const FormData = require('form-data');
const { forOwn } = require('lodash');
const path = require('path');
const lpad = (str, width) => {
let paddedStr = str;
while (paddedStr.length < width) {
@@ -14,7 +19,33 @@ const rpad = (str, width) => {
return paddedStr;
};
const createFormData = (datas, collectionPath) => {
// make axios work in node using form data
// reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427
const form = new FormData();
forOwn(datas, (value, key) => {
if (typeof value == 'string') {
form.append(key, value);
return;
}
const filePaths = value || [];
filePaths?.forEach?.((filePath) => {
let trimmedFilePath = filePath.trim();
if (!path.isAbsolute(trimmedFilePath)) {
trimmedFilePath = path.join(collectionPath, trimmedFilePath);
}
form.append(key, fs.createReadStream(trimmedFilePath), path.basename(trimmedFilePath));
});
});
return form;
};
module.exports = {
lpad,
rpad
rpad,
createFormData
};