fix: multipart/mixed and multipart/form-data interpolation and generic request behaviour (#8087)

* fix: multipart spec additions and interpolation fixes

* test(cli): add interpolation multipart  tests

* Update packages/bruno-tests/collection/multipart/multipart-mixed-form-data-parse.bru

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: remove assert as curl also gives the same result

* chore: codestyle

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Sid
2026-05-25 20:05:50 +05:30
committed by GitHub
parent 87d97ba0ef
commit a3e3199490
9 changed files with 331 additions and 4 deletions

View File

@@ -102,7 +102,9 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
}));
}
} else if (contentType.startsWith('multipart/')) {
if (Array.isArray(request?.data) && !isFormData(request.data)) {
if (request?.data && typeof request.data === 'string') {
request.data = _interpolate(request.data);
} else if (Array.isArray(request?.data) && !isFormData(request.data)) {
try {
request.data = request?.data?.map((d) => ({
...d,

View File

@@ -487,7 +487,7 @@ const runSingleRequest = async function (
const contentType = contentTypeHeader ? request.headers[contentTypeHeader] : '';
if (typeof contentType === 'string' && contentType.startsWith('multipart/')) {
if (!isFormData(request?.data)) {
if (typeof request.data !== 'string' && !isFormData(request?.data)) {
request._originalMultipartData = request.data;
request.collectionPath = collectionPath;
let form = createFormData(request.data, collectionPath);

View File

@@ -18,6 +18,58 @@ describe('interpolate-vars: interpolateVars', () => {
const result = interpolateVars(request, { shouldNotApply: 'value' }, null, null);
expect(result.data).toBe(streamPayload);
});
it('preserves raw string body when Content-Type is multipart/mixed', () => {
const rawMultipartBody = [
'--TestBoundary123',
'Content-Type: application/json',
'',
'{"test": true}',
'--TestBoundary123--',
''
].join('\r\n');
const request = {
method: 'POST',
mode: 'text',
url: 'https://httpbin.dev/post',
headers: { 'content-type': 'multipart/mixed; boundary=TestBoundary123' },
data: rawMultipartBody
};
const result = interpolateVars(request, {}, null, null);
expect(result.data).toBe(rawMultipartBody);
});
it('interpolates variables in raw multipart/mixed string body', () => {
const boundary = 'CustomBoundary123';
const rawMultipartBody = [
`--${boundary}`,
'Content-Type: text/plain',
'',
'Token: {{token}}',
`--${boundary}`,
'Content-Type: application/json',
'',
'{"id": "{{id}}", "msg": "{{msg}}"}',
`--${boundary}--`,
''
].join('\r\n');
const request = {
method: 'POST',
mode: 'text',
url: 'https://api.example/send',
headers: { 'content-type': `multipart/mixed; boundary=${boundary}` },
data: rawMultipartBody
};
const result = interpolateVars(request, { token: 'abc123', id: 42, msg: 'hello' }, null, null);
expect(result.data).toContain('Token: abc123');
expect(result.data).toContain('{"id": "42", "msg": "hello"}');
expect(result.data).toContain(`--${boundary}`);
expect(result.data).toContain(`--${boundary}--`);
});
});
describe('interpolate-vars: api key header name sidecar', () => {