# Posting PDF-files multipart/form-data solution

**URL:** <https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914>\
**Category:** General\
**Tags:** http-request\
**Created:** [24 February 2022 09:35 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914 "2022-02-24T09:35:25Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![VincentSC](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/vincentsc/32/57287_2.png) [@VincentSC](https://discourse.nodered.org/u/VincentSC)\
**Post date:** [24 February 2022 09:35 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/1 "2022-02-24T09:35:25Z")

</div>

As I did not find a good solution before, this is how you post a binary file to `http-request`. The solution is: make sure that payload _always_ is a buffer and _never_ a string. No need to do all kinds of binary or base64 conversions, just make sure always a buffer is sent and never a string.

I started with [File Upload using HTTP Request node (flow) - Node-RED](https://flows.nodered.org/flow/cbf44e064b9406a1175a7e8d589f66ac) that works well for text-files. For a version that works with both text and binary data (and has some boundary-=optimizations), you need to replace the contents of `Format the header and payload` with:

```auto
const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');

let boundary = "------------------------"+genRanHex(16);

msg.headers = {
    "Content-Type": "multipart/form-data; boundary="+boundary
}

let data_pre = Buffer.from("--"+boundary+'\r\n'+
"Content-Disposition: form-data; name=\"file\"; filename=\""+msg.filename+"\"\r\n"+
"Content-Type: application/octet-stream\r\n"+
"\r\n", "utf-8");

let data_post = Buffer.from("\r\n"+
"--"+boundary+"--\r\n", "utf-8");

msg.payload = Buffer.concat([data_pre, msg.payload, data_post]);

return msg;

```

Tested with a posted file being redirected to a http-request (with this code) and a resulting file being sent back to the browser.

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [25 February 2022 03:47 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/2 "2022-02-25T03:47:40Z")

</div>

Hi Vincent -- thanks for taking the time to post your solution! I, too, have spent a good bit of time trying to piece together a multipart/form-data compliant payload that my Spring apis would accept. I'm not sure why there is no editor panel for the core `http-request` node, that would allow the user to include an array of files, buffers, and key/value pairs... or why I never offered to contribute that feature... hmmm.

Lately I've been referring to [this answer](https://discourse.nodered.org/t/form-data-multipart-encoded-request-with-pdf-file-attached-into-the-body/44749/2) from Nick for a bit simpler JS function example. It does require that your binary data be in a Buffer, but it avoids the user generated boundaries and interspersed CR/NL bits that are hard to find when they are not perfectly placed.

Welcome to the node-red community!

---

<div class="post-metadata">

**Author:** ![VincentSC](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/vincentsc/32/57287_2.png) [@VincentSC](https://discourse.nodered.org/u/VincentSC)\
**Post date:** [25 February 2022 09:29 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/3 "2022-02-25T09:29:45Z")

</div>

That is much cleaner! Thanks!

This is the same as the above, but then a change-node instead of a function-node.

```auto
[
    {
        "id": "6cfb8852c3a4e6b0",
        "type": "change",
        "z": "792580e9.3d65e8",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\t \"file\":{\t \"value\":payload,\t \"options\":{\"filename\":filename}\t }\t}",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "headers",
                "pt": "msg",
                "to": "{\"content-type\":\"multipart/form-data\"}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 820,
        "y": 2060,
        "wires": [
            [
                "fb27d4abe3afbb2a",
                "fda054cb98806e70"
            ]
        ]
    }
]

```

Lots of NodeRed is quite messy and buggy, so it's difficult to find good answers.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [25 February 2022 10:07 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/4 "2022-02-25T10:07:27Z")

</div>

> [@VincentSC](#):
>
> Lots of NodeRed is quite messy and buggy, so it's difficult to find good answers.

The help sidebar for the HTTP Request node tells you how to do a file upload.

> File Upload
> 
> To perform a file upload, `msg.headers["content-type"]` should be set to `multipart/form-data` and the `msg.payload` passed to the node must be an object with the following structure:
> 
> ```auto
> {
> "KEY": {
> "value": FILE_CONTENTS,
> "options": {
> "filename": "FILENAME"
> }
> }
> }
> 
> ```
> 
> The values of `KEY` , `FILE_CONTENTS` and `FILENAME` should be set to the appropriate values.

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [25 February 2022 13:02 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/5 "2022-02-25T13:02:18Z")

</div>

For completeness, allow me to ask the follow on question in this thread...

What is the syntax to use for a multipart body that contains an array of form data, json content, and several files to be uploaded?

---

<div class="post-metadata">

**Author:** ![VincentSC](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/vincentsc/32/57287_2.png) [@VincentSC](https://discourse.nodered.org/u/VincentSC)\
**Post date:** [25 February 2022 13:55 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/6 "2022-02-25T13:55:33Z")

</div>

> [@knolleary](#):
>
> The help sidebar for the HTTP Request node tells you how to do a file upload.

Ah, true! I did not scroll to the end. Just I assumed I had to fix things, again. Good your node is a good exception to messy NodeRed-land.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [25 February 2022 13:57 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/7 "2022-02-25T13:57:28Z")

</div>

> [@VincentSC](#):
>
> Good your node is a good exception to messy NodeRed-land.

We try to ensure all the core nodes set a good example.

If you have feedback on other nodes, I encourage you to share it with the node author to help improve things.

---

<div class="post-metadata">

**Author:** ![VincentSC](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/vincentsc/32/57287_2.png) [@VincentSC](https://discourse.nodered.org/u/VincentSC)\
**Post date:** [25 February 2022 14:05 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/8 "2022-02-25T14:05:44Z")

</div>

> [@knolleary](#):
>
> If you have feedback on other nodes, I encourage you to share it with the node author to help improve things.

Biggest problem is that many nodes are at WFM-level. Then you get even situations like the complete msg being thrown away, or nodes that work under very specific situations only. A standard reaction is to fork to fix things quickly, but `node-red-controb-xxx-3` gets abandoned too.

I'm working on multiple ones needed for interaction with gitlab and mattermost APIs.

Is there a design-doc for plugins? Are there ways to mark projects as abandoned?

---

<div class="post-metadata">

**Author:** ![VincentSC](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/vincentsc/32/57287_2.png) [@VincentSC](https://discourse.nodered.org/u/VincentSC)\
**Post date:** [25 February 2022 14:10 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/9 "2022-02-25T14:10:17Z")

</div>

> [@shrickus](#):
>
> What is the syntax to use for a multipart body that contains an array of form data, json content, and several files to be uploaded?

Put the name of the file in "KEY". If one, then this is often defaulted to "file". Example of more files:

```auto
{
   "file1":{
       "value":payload.file[0].contents,
       "options":{"filename":payload.file[0].filename}
   },
   "file2":{
       "value":payload.file[1].contents,
       "options":{"filename":payload.file[1].filename}
   }
}

```

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [25 February 2022 14:28 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/10 "2022-02-25T14:28:17Z")

</div>

> [@VincentSC](#):
>
> Biggest problem is that many nodes are at WFM-level.

Again we would encourage you to point them out more publicly (in a polite manner) rather than jump straight to forking so we can possibly "help" the author try to improve their nodes. The latest packaging details are here - [Packaging : Node-RED](https://nodered.org/docs/creating-nodes/packaging) - and the recent work on scoring is also looking at ways to take note of nodes that seem to be abandoned.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [26 April 2022 14:28 UTC](https://discourse.nodered.org/t/posting-pdf-files-multipart-form-data-solution/58914/11 "2022-04-26T14:28:42Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
