Send a file with multipart/form-data to OctoPrint REST API

my msg object for the final http post request :

payload:
--------------------------d74496d66958873e
Content-Disposition: form-data; name="select"

true
--------------------------d74496d66958873e
Content-Disposition: form-data; name="print"

true
--------------------------d74496d66958873e
Content-Disposition: form-data; name="file"; filename="a_gcode.gcode"
Content-Type: application/octet-stream; 
my gcode
--------------------------d74496d66958873e--
_msgid: "XXXXXXXXX"
headers:
Content-Type: "multipart/form-data; boundary=------------------------d74496d66958873e"

my msg object after the request shown in the debug is:

payload: 
"Error: socket hang up : http://racka/aa/api/files/local?apikey=XXXXXXXXXXX

_msgid: same as before
headers: same as before

statusCode: "ECONNRESET"

What are the answers to the other questions?

  1. do you see any thing like a yellow triangle?
    Yes
  2. What do you see when you hover over it?
    the yellow triangle said:
    no semi - colon: fixed
    msg already defined: changed name of returned variable to gcode
  3. What do you think that means?
  4. have you read https://nodered.org/docs/user-guide/messages ?
    Yes
  5. do you understand it?
    For the most part

Sometimes the error is "Error: write EPIPE" as opposed to socket hang up

Great you fixed that part! Now you have an error
"Error: socket hang up : http://racka/aa/api/files/local?apikey=XXXXXXXXXXX
what happens if you try that URL in a browser window?

That's good to hear, thank you for your help. Trying that url gives me

{
  "files": [], 
  "free": 58407620608, 
  "total": 62811418624
}

I have managed to get a file upload to work using a test gcode, putting "M117" in the gcode section.

In the multipart/form-data I have the gcode buffer converted to to string:

msg.req.files[0].buffer.toString()

where msg.req.files[0].buffer is:

[59,32,103,101,110,101,114,97,116,101,100,32,98,121,32,83,108,105,99,51,114,32,80,114,117,115,97,32,69,100,105,116,105,111,110,32,49,46,52,49,46,51,43,32,111,110,32,50,48,49,57,45,48,52,45,48,56,32,97,116,32,49,50,58,50,54,58,49,52,10,10,59,32,10,10,59,32,101,120,116,101,114,110,97,108,32,112,101,114,105,109,101,116,101,114,115,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,53,109,109,10,59,32,112,101,114,105,109,101,116,101,114,115,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,53,109,109,10,59,32,105,110,102,105,108,108,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,53,109,109,10,59,32,115,111,108,105,100,32,105,110,102,105,108,108,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,53,109,109,10,59,32,116,111,112,32,105,110,102,105,108,108,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,48,109,109,10,59,32,102,105,114,115,116,32,108,97,121,101,114,32,101,120,116,114,117,115,105,111,110,32,119,105,100,116,104,32,61,32,48,46,52,50,109,109,10,10,77,55,51,32,80,48,32,82,57,57,10,77,55,51,32,81,48,32,83,49,48,48,10,77,50,48,49,32,88,49,48,48,48,32,89,49,48,48,48,32,90,49,48,48,48,32,69,53,48,48,48,32,59,32,115,101,116,115,32,109,97,120,105,109,117,109,32,97,99,99,101,108,101,114,97,116,105,111,110,115,44,32,109,109,47,115,101,99,94,50,10,77,50,48,51,32,88,50,48,48,32,89,50,48,48,32,90,49,50,32,69,49,50,48,32,59,32,115,101,116,115,32,109,97,120,105,109,117,109,32,102,101,101,100,114,97,116,101,115,44,32,109,109,47,115,101,99,10,77,50,48,52,32,80,49,50,53,48,32,82,49,50,53,48,32,84,49,50,53,48,32,59,32,115,101,116,115,32,97,99,99,101,108,101,114,97,116,105,111,110,32,40,80,44,32,84,41,32,97,110,100,32,114,101,116,114,97,99,116,32,97,99,99,101,108,101,114,97,116,105,111,110,32,40,82,41,44,32,109,109,47,115,101,99,94,50,10,77,50,48,53,32,88,56,46,48,48,32,89,56,46,48,48,32,90,48,46,52,48,32,69,49,46,53,48,32,59,32,115,101,116,115,32,116,104,101,32,106,101,114,107,32,108,105,109,105,116,115,44,32,109,109,47,115,101,99,10,77,50,48,53,32,83,48,32,84,48,32,59,32,115,101,116,115,32,116,104,101,32,109,105,110,105,109,117,109,32,101,120,116,114,117,100,105,110,103,32,97,110,100,32,116,114,97,118,101,108,32,102,101,101,100,32,114,97,116,101,44,32,109,109,47,115,101,99,10,77,49,48,55,10,77,49,49,53,32,85,51,46,53,46,49,32,59,32,116,101,108,108,32,112,114,105,110,116,101,114,32,108,97,116,101,115,116,32,102,119,32,118,101,114,115,105,111,110,10,77,56,51,32,32,59,32,101,120,116,114,117,100,101,114,32,114,101,108,97,116,105,118,101,32,109,111,100,101,10,77,49,48,52,32,83,50,49,53,32,59,32,115,101,116,32,101,120,116,114,117,100,101,114,32,116,101,109,112,10,77,49,52,48,32,83,54,48,32,59,32,115,101,116,32,98,101,100,32,116,101,109,112,10,77,49,57,48,32,83,54,48,32,59,32,119,97,105,116,32,102,111,114,32,98,101,100,32,116,101,109,112,10,77,49,48,57,32,83,50,49,53,32,59,32,119,97,105,116,32,102,111,114,32,101,120,116,114,117,100,101,114,32,116,101,109,112,10,71,50,56,32,87,32,59,32,104,111,109,101,32,97,108,108,32,119,105,116,104,111,117,116,32,109,101,115,104,32,98,101,100,32,108,101,118,101,108,10,71,56,48,32,59,32,109,101,115,104,32,98,101,100,32,108,101,118,101,108,105,110,103,10,71,49,32,89,45,51,46,48,32,70,49,48,48,48,46,48,32,59,32,103,111,32,111,117,116,115,105,100,101,32,112,114,105,110,116,32,97,114,101,97,10,71,57,50,32,69,48,46,48,10,71,49,32,88,54,48,46,48,32,69]

Converting it to a string gives me a string which appears readable but evidently not so to octoprint

Just as a side question, why not use the Octoprint built in file upload? I do it all the time to upload files from my Mac to the RPi running Octoprint.

I am trying to view multiple instances of Octoprint on a single dashboard, so it would be useful to be able to upload files without going to the main page of each instance. I'm going to shelve this one for now I think, thank you for your help though.

@knolleary: Has there been any development on the HTTP-request node, to support multipart/upload of a file-buffer (or base64 encoded) (e.g .pdf) file along with some JSON out of the box?

Or is it still required to build the request by hand in a function node like in the old example from 2019?

@jmk-randers the Request node has had file upload support in it since v0.20 released in March 2019. The sidebar help for the node describes how to do it.

@knolleary: thanks for confirming it, I have tried POSTing a multipart with some JSON metadata first and then a filebuffer using the structure described

{
    "KEY": {
        "value": FILE_CONTENTS,
        "options": {
            "filename": "FILENAME"
        }
    }
}

as described.

My msg.headers are set to:

{
   "Content-Type":"multipart/form-data",
   "Accept":"application/json",
   "Authorization":"Bearer "
}

My payload are structured like this (values mocked up for data-protection):

{
    "CaseID":1234567890,
    "DocumentName":"Testing .pdf POST",
    "Casepart":{
                         "PartId":12345,
                         "PartType":"Person"
                       },
     "Documenttype":
                   {
                        "Id":1,
                        "Name":"TestName"
                    },
   "Beskrivelse":"Test",
   "file":{
               "value": [37,_values left out for readability_,80],
               "options": {
                                  "filename":
                                  "test.pdf"}
                                }
}

The reply i get from the endpoint though is ""Object reference not set to an instance of an object." which indicates that one of my values is empty or malformed or maybe that the endpoint cannot recieve the data in this format..

Heres my flow with sensistive data removed:

[{"id":"e39491ff.49538","type":"pdfmake","z":"f08e748.bb67888","name":"","outputType":"Buffer","inputProperty":"payload","options":"{}","outputProperty":"filebuffer","x":280,"y":60,"wires":[["f20736f5.799d08","88e8a48f.723278"]]},{"id":"d8ae17d6.85ee48","type":"inject","z":"f08e748.bb67888","name":"Test Data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"content\":[\"First paragraph\",\"Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines\"]}","payloadType":"json","x":100,"y":60,"wires":[["e39491ff.49538"]]},{"id":"f20736f5.799d08","type":"debug","z":"f08e748.bb67888","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"filebuffer","targetType":"msg","statusVal":"","statusType":"auto","x":360,"y":120,"wires":[]},{"id":"88e8a48f.723278","type":"change","z":"f08e748.bb67888","name":"request parametre","rules":[{"t":"set","p":"headers","pt":"msg","to":"{\"Content-Type\":\"multipart/form-data\",\"Accept\":\"application/json\",\"Authorization\":\" \"}","tot":"json"},{"t":"set","p":"access_method","pt":"msg","to":"Bearer","tot":"str"},{"t":"set","p":"headers.Authorization","pt":"msg","to":"access_method & \" \" & $flowContext('access_token')","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"{\"CaseID\":1234567890,\"DocumentName\":\"Testing .pdf POST\",\"Casepart\":{\"PartId\":12345,\"PartType\":\"Person\"},\"Documenttype\":{\"Id\":1,\"Name\":\"TestName\"},\"Beskrivelse\":\"Test\",\"file\":{\"value\":\"\",\"options\":{\"filename\":\"\"}}}","tot":"json"},{"t":"set","p":"url","pt":"msg","to":"endpointurl","tot":"env"},{"t":"set","p":"method","pt":"msg","to":"POST","tot":"str"},{"t":"set","p":"payload.file.options.filename","pt":"msg","to":"test.pdf","tot":"str"},{"t":"set","p":"payload.file.value","pt":"msg","to":"filebuffer","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":60,"wires":[["83fc6a59.f49988","9895b6e0.172548","d8424031.e4c7"]]},{"id":"d8424031.e4c7","type":"http request","z":"f08e748.bb67888","name":"","method":"use","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":710,"y":60,"wires":[["c58d18bc.854a28"]]},{"id":"c58d18bc.854a28","type":"debug","z":"f08e748.bb67888","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":890,"y":60,"wires":[]},{"id":"83fc6a59.f49988","type":"debug","z":"f08e748.bb67888","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"headers","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":160,"wires":[]},{"id":"9895b6e0.172548","type":"debug","z":"f08e748.bb67888","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":200,"wires":[]}]

Any inputs?

I have read the following post to try and get a bit wiser.. but to no avail (so far)

https://flows.nodered.org/flow/cbf44e064b9406a1175a7e8d589f66ac

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