From bce40148a6bbfac22fc82d3d281d3a51e20f5ed3 Mon Sep 17 00:00:00 2001 From: ricardo Date: Mon, 23 Mar 2020 09:11:29 -0400 Subject: [PATCH 1/2] :sparkles: Extended multipart/form-data functionality --- packages/nodes-base/nodes/HttpRequest.node.ts | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/nodes-base/nodes/HttpRequest.node.ts b/packages/nodes-base/nodes/HttpRequest.node.ts index 46334110f..f7fb7cf61 100644 --- a/packages/nodes-base/nodes/HttpRequest.node.ts +++ b/packages/nodes-base/nodes/HttpRequest.node.ts @@ -7,6 +7,7 @@ import { INodeExecutionData, INodeType, INodeTypeDescription, + IBinaryData, } from 'n8n-workflow'; import { OptionsWithUri } from 'request'; @@ -636,10 +637,15 @@ export class HttpRequest implements INodeType { const sendBinaryData = this.getNodeParameter('sendBinaryData', itemIndex, false) as boolean; if (sendBinaryData === true) { - if (options.bodyContentType !== 'raw') { + const contentTypesAllowed = [ + 'raw', + 'multipart-form-data', + ]; + + if (!contentTypesAllowed.includes(options.bodyContentType as string)) { // As n8n-workflow.NodeHelpers.getParamterResolveOrder can not be changed // easily to handle parameters in dot.notation simply error for now. - throw new Error('Sending binary data is only supported when option "Body Content Type" is set to "RAW/CUSTOM"!'); + throw new Error('Sending binary data is only supported when option "Body Content Type" is set to "RAW/CUSTOM" and "FORM-DATA/MULTIPART"!'); } const item = items[itemIndex]; @@ -653,7 +659,22 @@ export class HttpRequest implements INodeType { throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`); } - requestOptions.body = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + const binaryProperty = item.binary[binaryPropertyName] as IBinaryData; + + if (options.bodyContentType === 'raw') { + requestOptions.body = Buffer.from(binaryProperty.data, BINARY_ENCODING); + } + if (options.bodyContentType === 'multipart-form-data') { + requestOptions.body = { + file: { + value: Buffer.from(binaryProperty.data, BINARY_ENCODING), + options: { + filename: binaryProperty.fileName, + contentType: binaryProperty.mimeType, + }, + } + }; + } continue; } } From d710909bbde581bc7336116016ba76911897b93b Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Mon, 30 Mar 2020 10:31:33 +0200 Subject: [PATCH 2/2] :zap: Add support to send multiple files with Form-Data Multipart --- packages/nodes-base/nodes/HttpRequest.node.ts | 59 ++++++++++++------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/nodes-base/nodes/HttpRequest.node.ts b/packages/nodes-base/nodes/HttpRequest.node.ts index f7fb7cf61..5afc2bb74 100644 --- a/packages/nodes-base/nodes/HttpRequest.node.ts +++ b/packages/nodes-base/nodes/HttpRequest.node.ts @@ -357,7 +357,9 @@ export class HttpRequest implements INodeType { ], }, }, - description: 'Name of the binary property which contains
the data for the file to be uploaded.', + description: `Name of the binary property which contains the data for the file to be uploaded.
+ For Form-Data Multipart, multiple can be provided in the format:
+ "sendKey1:binaryProperty1,sendKey2:binaryProperty2`, }, { displayName: 'Body Parameters', @@ -645,7 +647,7 @@ export class HttpRequest implements INodeType { if (!contentTypesAllowed.includes(options.bodyContentType as string)) { // As n8n-workflow.NodeHelpers.getParamterResolveOrder can not be changed // easily to handle parameters in dot.notation simply error for now. - throw new Error('Sending binary data is only supported when option "Body Content Type" is set to "RAW/CUSTOM" and "FORM-DATA/MULTIPART"!'); + throw new Error('Sending binary data is only supported when option "Body Content Type" is set to "RAW/CUSTOM" or "FORM-DATA/MULTIPART"!'); } const item = items[itemIndex]; @@ -654,26 +656,43 @@ export class HttpRequest implements INodeType { throw new Error('No binary data exists on item!'); } - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string; - if (item.binary[binaryPropertyName] === undefined) { - throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const binaryProperty = item.binary[binaryPropertyName] as IBinaryData; - if (options.bodyContentType === 'raw') { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string; + if (item.binary[binaryPropertyName] === undefined) { + throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`); + } + const binaryProperty = item.binary[binaryPropertyName] as IBinaryData; requestOptions.body = Buffer.from(binaryProperty.data, BINARY_ENCODING); - } - if (options.bodyContentType === 'multipart-form-data') { - requestOptions.body = { - file: { - value: Buffer.from(binaryProperty.data, BINARY_ENCODING), - options: { - filename: binaryProperty.fileName, - contentType: binaryProperty.mimeType, - }, - } - }; + } else if (options.bodyContentType === 'multipart-form-data') { + requestOptions.body = {}; + const binaryPropertyNameFull = this.getNodeParameter('binaryPropertyName', itemIndex) as string; + const binaryPropertyNames = binaryPropertyNameFull.split(',').map(key => key.trim()); + + for (const propertyData of binaryPropertyNames) { + let propertyName = 'file'; + let binaryPropertyName = propertyData; + if (propertyData.includes(':')) { + const propertyDataParts = propertyData.split(':'); + propertyName = propertyDataParts[0]; + binaryPropertyName = propertyDataParts[1]; + } else if (binaryPropertyNames.length > 1) { + throw new Error('If more than one property should be send it is needed to define the in the format: "sendKey1:binaryProperty1,sendKey2:binaryProperty2"'); + } + + if (item.binary[binaryPropertyName] === undefined) { + throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryProperty = item.binary[binaryPropertyName] as IBinaryData; + + requestOptions.body[propertyName] = { + value: Buffer.from(binaryProperty.data, BINARY_ENCODING), + options: { + filename: binaryProperty.fileName, + contentType: binaryProperty.mimeType, + }, + }; + } } continue; }