mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
fix: preserve stream-backed file bodies during request interpolation (#7690)
This commit is contained in:
committed by
GitHub
parent
f8bf1460bd
commit
975c638f39
@@ -2,6 +2,8 @@ const { interpolate } = require('@usebruno/common');
|
||||
const { each, forOwn, cloneDeep, find } = require('lodash');
|
||||
const { isFormData } = require('@usebruno/common').utils;
|
||||
|
||||
const isBinaryRequestBody = (data) => Buffer.isBuffer(data) || typeof data?.pipe === 'function';
|
||||
|
||||
const getContentType = (headers = {}) => {
|
||||
let contentType = '';
|
||||
forOwn(headers, (value, key) => {
|
||||
@@ -80,7 +82,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
|
||||
// Skip body interpolation for GraphQL requests.
|
||||
if (!isGraphqlRequest) {
|
||||
if (contentType.includes('json') && !Buffer.isBuffer(request.data)) {
|
||||
if (contentType.includes('json') && !isBinaryRequestBody(request.data)) {
|
||||
if (typeof request.data === 'string') {
|
||||
if (request?.data?.length) {
|
||||
request.data = _interpolate(request.data, { escapeJSONStrings: true });
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
const { describe, it, expect } = require('@jest/globals');
|
||||
const interpolateVars = require('../../src/runner/interpolate-vars');
|
||||
|
||||
describe('interpolate-vars: interpolateVars', () => {
|
||||
it('keeps stream-backed JSON request bodies intact', () => {
|
||||
const streamPayload = {
|
||||
pipe: jest.fn(),
|
||||
path: '/tmp/allocations.json'
|
||||
};
|
||||
const request = {
|
||||
method: 'POST',
|
||||
mode: 'file',
|
||||
url: 'http://api.example/upload',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
data: streamPayload
|
||||
};
|
||||
|
||||
const result = interpolateVars(request, { shouldNotApply: 'value' }, null, null);
|
||||
expect(result.data).toBe(streamPayload);
|
||||
});
|
||||
});
|
||||
|
||||
describe('interpolate-vars: api key header name sidecar', () => {
|
||||
it('interpolates apiKeyHeaderName in lockstep with interpolated header keys', () => {
|
||||
const request = {
|
||||
|
||||
@@ -2,6 +2,8 @@ const { interpolate } = require('@usebruno/common');
|
||||
const { each, forOwn, cloneDeep } = require('lodash');
|
||||
const { isFormData } = require('@usebruno/common').utils;
|
||||
|
||||
const isBinaryRequestBody = (data) => Buffer.isBuffer(data) || typeof data?.pipe === 'function';
|
||||
|
||||
const getContentType = (headers = {}) => {
|
||||
let contentType = '';
|
||||
forOwn(headers, (value, key) => {
|
||||
@@ -110,10 +112,11 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
|
||||
if (typeof contentType === 'string' && !isGraphqlRequest) {
|
||||
/*
|
||||
We explicitly avoid interpolating buffer values because the file content is read as a buffer object in raw body mode.
|
||||
Even if the selected file's content type is JSON, this prevents the buffer object from being interpolated.
|
||||
We explicitly avoid interpolating binary payloads because raw file bodies can be represented as
|
||||
buffers or streams depending on size. Even if the selected file's content type is JSON, the
|
||||
transport object itself must not be interpolated.
|
||||
*/
|
||||
if (contentType.includes('json') && !Buffer.isBuffer(request.data)) {
|
||||
if (contentType.includes('json') && !isBinaryRequestBody(request.data)) {
|
||||
if (typeof request.data === 'string') {
|
||||
if (request.data.length) {
|
||||
request.data = _interpolate(request.data, {
|
||||
|
||||
@@ -426,4 +426,24 @@ describe('interpolate-vars: interpolateVars', () => {
|
||||
expect(result.data).toContain('--TestBoundary123--');
|
||||
});
|
||||
});
|
||||
|
||||
describe('File body streaming', () => {
|
||||
it('keeps stream-backed JSON request bodies intact', () => {
|
||||
const streamPayload = {
|
||||
pipe: jest.fn(),
|
||||
path: '/tmp/allocations.json'
|
||||
};
|
||||
const request = {
|
||||
method: 'POST',
|
||||
mode: 'file',
|
||||
url: 'http://api.example/upload',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
data: streamPayload
|
||||
};
|
||||
|
||||
const result = interpolateVars(request, { shouldNotApply: 'value' }, null, null);
|
||||
|
||||
expect(result.data).toBe(streamPayload);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user