mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-27 06:34:06 +00:00
Merge pull request #5713 from barelyhuman/fix/form-values-seq-5237
fix: reimplement payload serialization for `x-www-form-encoded`
This commit is contained in:
committed by
GitHub
parent
c2d40fe99f
commit
924bc2e79e
@@ -80,12 +80,11 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
}
|
||||
}
|
||||
} else if (contentType === 'application/x-www-form-urlencoded') {
|
||||
if (typeof request.data === 'object') {
|
||||
try {
|
||||
forOwn(request?.data, (value, key) => {
|
||||
request.data[key] = _interpolate(value);
|
||||
});
|
||||
} catch (err) {}
|
||||
if (request.data && Array.isArray(request.data)) {
|
||||
request.data = request.data.map((d) => ({
|
||||
...d,
|
||||
value: _interpolate(d?.value)
|
||||
}));
|
||||
}
|
||||
} else if (contentType === 'multipart/form-data') {
|
||||
if (Array.isArray(request?.data) && !(request.data instanceof FormData)) {
|
||||
|
||||
@@ -6,7 +6,6 @@ const decomment = require('decomment');
|
||||
const crypto = require('node:crypto');
|
||||
const fs = require('node:fs');
|
||||
const { mergeHeaders, mergeScripts, mergeVars, mergeAuth, getTreePathFromCollectionToItem } = require('../utils/collection');
|
||||
const { buildFormUrlEncodedPayload } = require('../utils/form-data');
|
||||
const path = require('node:path');
|
||||
const { isLargeFile } = require('../utils/filesystem');
|
||||
const { getFormattedOauth2Credentials } = require('../utils/oauth2');
|
||||
@@ -356,7 +355,7 @@ const prepareRequest = async (item = {}, collection = {}) => {
|
||||
axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
const enabledParams = filter(request.body.formUrlEncoded, (p) => p.enabled);
|
||||
axiosRequest.data = buildFormUrlEncodedPayload(enabledParams);
|
||||
axiosRequest.data = enabledParams;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'multipartForm') {
|
||||
|
||||
@@ -19,7 +19,7 @@ const { shouldUseProxy, PatchedHttpsProxyAgent, getSystemProxyEnvVariables } = r
|
||||
const path = require('path');
|
||||
const { parseDataFromResponse } = require('../utils/common');
|
||||
const { getCookieStringForUrl, saveCookies } = require('../utils/cookies');
|
||||
const { createFormData } = require('../utils/form-data');
|
||||
const { createFormData, buildFormUrlEncodedPayload } = require('../utils/form-data');
|
||||
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
|
||||
const { NtlmClient } = require('axios-ntlm');
|
||||
const { addDigestInterceptor } = require('@usebruno/requests');
|
||||
@@ -333,7 +333,7 @@ const runSingleRequest = async function (
|
||||
name => name.toLowerCase() === 'content-type'
|
||||
);
|
||||
if (contentTypeHeader && request.headers[contentTypeHeader] === 'application/x-www-form-urlencoded') {
|
||||
request.data = qs.stringify(request.data, { arrayFormat: 'repeat' });
|
||||
request.data = buildFormUrlEncodedPayload(request.data);
|
||||
}
|
||||
|
||||
if (contentTypeHeader && request.headers[contentTypeHeader] === 'multipart/form-data') {
|
||||
@@ -406,7 +406,7 @@ const runSingleRequest = async function (
|
||||
});
|
||||
|
||||
if (request.ntlmConfig) {
|
||||
axiosInstance=NtlmClient(request.ntlmConfig,axiosInstance.defaults)
|
||||
axiosInstance = NtlmClient(request.ntlmConfig, axiosInstance.defaults);
|
||||
delete request.ntlmConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,14 @@ const path = require('path');
|
||||
|
||||
/**
|
||||
* @param {Array.<object>} params The request body Array
|
||||
* @returns {object} Returns an obj with repeating key as an array of values
|
||||
* {item: 2, item: 3, item1: 4} becomes {item: [2,3], item1: 4}
|
||||
* @returns {string} Returns a order respecting standard compliant string of form encoded values
|
||||
*/
|
||||
const buildFormUrlEncodedPayload = (params) => {
|
||||
return params.reduce((acc, p) => {
|
||||
if (!acc[p.name]) {
|
||||
acc[p.name] = p.value;
|
||||
} else if (Array.isArray(acc[p.name])) {
|
||||
acc[p.name].push(p.value);
|
||||
} else {
|
||||
acc[p.name] = [acc[p.name], p.value];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
const resultParams = new URLSearchParams();
|
||||
for (const param of params) {
|
||||
resultParams.append(param.name, param.value);
|
||||
}
|
||||
return resultParams.toString();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../util
|
||||
const { uuid, safeStringifyJSON, safeParseJSON, parseDataFromResponse, parseDataFromRequest } = require('../../utils/common');
|
||||
const { chooseFileToSave, writeBinaryFile, writeFile } = require('../../utils/filesystem');
|
||||
const { addCookieToJar, getDomainsWithCookies, getCookieStringForUrl } = require('../../utils/cookies');
|
||||
const { createFormData } = require('../../utils/form-data');
|
||||
const { createFormData, buildFormUrlEncodedPayload } = require('../../utils/form-data');
|
||||
const { findItemInCollectionByPathname, sortFolder, getAllRequestsInFolderRecursively, getEnvVars, getTreePathFromCollectionToItem, mergeVars, sortByNameThenSequence } = require('../../utils/collection');
|
||||
const { getOAuth2TokenUsingAuthorizationCode, getOAuth2TokenUsingClientCredentials, getOAuth2TokenUsingPasswordCredentials, getOAuth2TokenUsingImplicitGrant, updateCollectionOauth2Credentials } = require('../../utils/oauth2');
|
||||
const { preferencesUtil } = require('../../store/preferences');
|
||||
@@ -424,7 +424,7 @@ const registerNetworkIpc = (mainWindow) => {
|
||||
|
||||
// stringify the request url encoded params
|
||||
if (request.headers['content-type'] === 'application/x-www-form-urlencoded') {
|
||||
request.data = qs.stringify(request.data, { arrayFormat: 'repeat' });
|
||||
request.data = buildFormUrlEncodedPayload(request.data);
|
||||
}
|
||||
|
||||
if (request.headers['content-type'] === 'multipart/form-data') {
|
||||
|
||||
@@ -104,12 +104,11 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
|
||||
} catch (err) {}
|
||||
}
|
||||
} else if (contentType === 'application/x-www-form-urlencoded') {
|
||||
if (typeof request.data === 'object') {
|
||||
try {
|
||||
forOwn(request?.data, (value, key) => {
|
||||
request.data[key] = _interpolate(value);
|
||||
});
|
||||
} catch (err) {}
|
||||
if (request.data && Array.isArray(request.data)) {
|
||||
request.data = request.data.map((d) => ({
|
||||
...d,
|
||||
value: _interpolate(d?.value)
|
||||
}));
|
||||
}
|
||||
} else if (contentType === 'multipart/form-data') {
|
||||
if (Array.isArray(request?.data) && !(request.data instanceof FormData)) {
|
||||
|
||||
@@ -422,7 +422,7 @@ const prepareRequest = async (item, collection = {}, abortController) => {
|
||||
axiosRequest.headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
const enabledParams = filter(request.body.formUrlEncoded, (p) => p.enabled);
|
||||
axiosRequest.data = buildFormUrlEncodedPayload(enabledParams);
|
||||
axiosRequest.data = enabledParams;
|
||||
}
|
||||
|
||||
if (request.body.mode === 'multipartForm') {
|
||||
|
||||
@@ -5,20 +5,14 @@ const path = require('path');
|
||||
|
||||
/**
|
||||
* @param {Array.<object>} params The request body Array
|
||||
* @returns {object} Returns an obj with repeating key as an array of values
|
||||
* {item: 2, item: 3, item1: 4} becomes {item: [2,3], item1: 4}
|
||||
* @returns {string} Returns a order respecting standard compliant string of form encoded values
|
||||
*/
|
||||
const buildFormUrlEncodedPayload = (params) => {
|
||||
return params.reduce((acc, p) => {
|
||||
if (!acc[p.name]) {
|
||||
acc[p.name] = p.value;
|
||||
} else if (Array.isArray(acc[p.name])) {
|
||||
acc[p.name].push(p.value);
|
||||
} else {
|
||||
acc[p.name] = [acc[p.name], p.value];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
const resultParams = new URLSearchParams();
|
||||
for (const param of params) {
|
||||
resultParams.append(param.name, param.value);
|
||||
}
|
||||
return resultParams.toString();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('prepare-request: prepareRequest', () => {
|
||||
|
||||
it('should handle single key-value pair', () => {
|
||||
const requestObj = [{ name: 'item', value: 2 }];
|
||||
const expected = { item: 2 };
|
||||
const expected = 'item=2';
|
||||
const result = buildFormUrlEncodedPayload(requestObj);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
@@ -33,7 +33,7 @@ describe('prepare-request: prepareRequest', () => {
|
||||
{ name: 'item1', value: 2 },
|
||||
{ name: 'item2', value: 3 }
|
||||
];
|
||||
const expected = { item1: 2, item2: 3 };
|
||||
const expected = 'item1=2&item2=3';
|
||||
const result = buildFormUrlEncodedPayload(requestObj);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
@@ -43,7 +43,7 @@ describe('prepare-request: prepareRequest', () => {
|
||||
{ name: 'item', value: 2 },
|
||||
{ name: 'item', value: 3 }
|
||||
];
|
||||
const expected = { item: [2, 3] };
|
||||
const expected = 'item=2&item=3';
|
||||
const result = buildFormUrlEncodedPayload(requestObj);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
@@ -54,7 +54,7 @@ describe('prepare-request: prepareRequest', () => {
|
||||
{ name: 'item2', value: 3 },
|
||||
{ name: 'item1', value: 4 }
|
||||
];
|
||||
const expected = { item1: [2, 4], item2: 3 };
|
||||
const expected = 'item1=2&item2=3&item1=4';
|
||||
const result = buildFormUrlEncodedPayload(requestObj);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user