Skip to content

Commit

Permalink
fix(HTTP Request Node): Always lowercase headers
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-radency authored and netroy committed May 2, 2023
1 parent 7136500 commit 31c56a1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
21 changes: 15 additions & 6 deletions packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
replaceNullValues,
sanitizeUiMessage,
} from '../GenericFunctions';
import { keysToLowercase } from '../../../utils/utilities';

function toText<T>(data: T) {
if (typeof data === 'object' && data !== null) {
Expand Down Expand Up @@ -1033,17 +1034,21 @@ export class HttpRequestV3 implements INodeType {
const body = this.getNodeParameter('body', itemIndex, '') as string;

const sendHeaders = this.getNodeParameter('sendHeaders', itemIndex, false) as boolean;

const headerParameters = this.getNodeParameter(
'headerParameters.parameters',
itemIndex,
[],
) as [{ name: string; value: string }];

const specifyHeaders = this.getNodeParameter(
'specifyHeaders',
itemIndex,
'keypair',
) as string;

const jsonHeadersParameter = this.getNodeParameter('jsonHeaders', itemIndex, '') as string;

const {
redirect,
batching,
Expand Down Expand Up @@ -1221,8 +1226,8 @@ export class HttpRequestV3 implements INodeType {
requestOptions.body = uploadData;
requestOptions.headers = {
...requestOptions.headers,
'Content-Length': contentLength,
'Content-Type': itemBinaryData.mimeType ?? 'application/octet-stream',
'content-length': contentLength,
'content-type': itemBinaryData.mimeType ?? 'application/octet-stream',
};
} else if (bodyContentType === 'raw') {
requestOptions.body = body;
Expand Down Expand Up @@ -1253,8 +1258,9 @@ export class HttpRequestV3 implements INodeType {

// Get parameters defined in the UI
if (sendHeaders && headerParameters) {
let additionalHeaders: IDataObject = {};
if (specifyHeaders === 'keypair') {
requestOptions.headers = headerParameters.reduce(parametersToKeyValue, {});
additionalHeaders = headerParameters.reduce(parametersToKeyValue, {});
} else if (specifyHeaders === 'json') {
// body is specified using JSON
try {
Expand All @@ -1269,8 +1275,12 @@ export class HttpRequestV3 implements INodeType {
);
}

requestOptions.headers = jsonParse(jsonHeadersParameter);
additionalHeaders = jsonParse(jsonHeadersParameter);
}
requestOptions.headers = {
...requestOptions.headers,
...keysToLowercase(additionalHeaders),
};
}

if (autoDetectResponseFormat || responseFormat === 'file') {
Expand All @@ -1290,7 +1300,7 @@ export class HttpRequestV3 implements INodeType {
requestOptions.headers = {};
}
const rawContentType = this.getNodeParameter('rawContentType', itemIndex) as string;
requestOptions.headers['Content-Type'] = rawContentType;
requestOptions.headers['content-type'] = rawContentType;
}

const authDataKeys: IAuthDataSanitizeKeys = {};
Expand Down Expand Up @@ -1338,7 +1348,6 @@ export class HttpRequestV3 implements INodeType {
try {
this.sendMessageToUI(sanitizeUiMessage(requestOptions, authDataKeys));
} catch (e) {}

if (authentication === 'genericCredentialType' || authentication === 'none') {
if (oAuth1Api) {
const requestOAuth1 = this.helpers.requestOAuth1.call(this, 'oAuth1Api', requestOptions);
Expand Down
35 changes: 34 additions & 1 deletion packages/nodes-base/test/utils/utilities.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fuzzyCompare } from '../../utils/utilities';
import { fuzzyCompare, keysToLowercase } from '../../utils/utilities';

//most test cases for fuzzyCompare are done in Compare Datasets node tests
describe('Test fuzzyCompare', () => {
Expand Down Expand Up @@ -29,3 +29,36 @@ describe('Test fuzzyCompare', () => {
expect(compareFunction(null, '0')).toEqual(false);
});
});

describe('Test keysToLowercase', () => {
it('should convert keys to lowercase', () => {
const headers = {
'Content-Type': 'application/json',
'X-Test-Header': 'Test',
Accept: 'application/json',
};

const newHeaders = keysToLowercase(headers);

expect(newHeaders).toEqual({
'content-type': 'application/json',
'x-test-header': 'Test',
accept: 'application/json',
});
});
it('should return original value if it is not an object', () => {
const test1 = keysToLowercase(['hello']);
const test2 = keysToLowercase('test');
const test3 = keysToLowercase(1);
const test4 = keysToLowercase(true);
const test5 = keysToLowercase(null);
const test6 = keysToLowercase(undefined);

expect(test1).toEqual(['hello']);
expect(test2).toEqual('test');
expect(test3).toEqual(1);
expect(test4).toEqual(true);
expect(test5).toEqual(null);
expect(test6).toEqual(undefined);
});
});
8 changes: 8 additions & 0 deletions packages/nodes-base/utils/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,11 @@ export const fuzzyCompare = (useFuzzyCompare: boolean, compareVersion = 1) => {
return isEqual(item1, item2);
};
};

export const keysToLowercase = <T>(headers: T) => {
if (typeof headers !== 'object' || Array.isArray(headers) || headers === null) return headers;
return Object.entries(headers).reduce((acc, [key, value]) => {
acc[key.toLowerCase()] = value;
return acc;
}, {} as IDataObject);
};

0 comments on commit 31c56a1

Please sign in to comment.