Torrent File Upload With HTTP Request Node Not Working

I'm trying to use the File Upload using HTTP Request node info as a basis for sending a torrent file to qBittorrent using the qBittorrent Web API, but I get a Error: 'gimp-2.10.34-setup.exe.torrent' is not a valid torrent file message that I can't seem to solve.

To make things as simple as possible, I started by importing the sample flow in the file upload doc and making minimal changes to meet the requirements from the web api doc. I've also made the same request in the Postman and the qBittorrent web API, both of which are successful. The only difference is that neither seems to show the actual binary data included in the headers.
Postman shows:

Content-Disposition: form-data; name="torrents"; filename="gimp-2.10.34-setup.exe.torrent"
<gimp-2.10.34-setup.exe.torrent>

Chrome shows:

Content-Disposition: form-data; name="fileselect[]"; filename="gimp-2.10.34-setup.exe.torrent"
Content-Type: application/x-bittorrent

The content-length header is causing its own problems and seems like it may be related to my issue:

  • In PostMan the content-length header is automatically set to 27595 for this particular torrent. When sending the headers with content-length set to the same value in the javascript function node, Node-Red stops working and shows a Error: Unexpected end of form error in the docker logs.
  • In the Node-Red debugger, the read file node outputs a payload containing a buffer object with a length of 26682. This matches the actual filesize reported by ls -la Setting the content-length header to this value results in the same error.
  • Commenting out the content-length header allows the payload to be sent without crashing Node-Red, but I'm not sure if this may be causing the error response from qBitTorrent.
  • When sending the request with no content-length header, and to a Node-Red HTTP In node instead of the qBitTorrent URL, the http request doesn't crash Node-Red and the incoming message has a msg.req.files[0].size of 46075. Setting the content-length header to this value results in the same error again.
  • The discrepancies in file size makes me wonder if the file is being re-encoded in a format that qBittorrent doesn't like, but I'm not sure how to determine if this is truly the case, or how to try to circumvent it.
  • When sending a small sample file.txt as specified in the example flow, the file size is consistent between leaving the read file node and coming in on the http in node. This seems to suggest that the issue with the fluctuating file size on the .torrent is related specifically to binary files.

I've also tried using the code snippets from the working Postman request inside a function node to try and isolate/work around the problem, but they all rely on dependencies that aren't available in Node-Red.

This is the current state of my flow:

[{"id":"b7fd9b1cfa901b50","type":"file in","z":"14758aa7.4be585","name":"","filename":"/data/files/gimp-2.10.34-setup.exe.torrent","filenameType":"str","format":"","chunk":false,"sendError":false,"encoding":"binary","allProps":false,"x":3940,"y":3480,"wires":[["25acf727c5e54ae2","df7f51e66675b1e8"]]},{"id":"2a077303fea284cf","type":"inject","z":"14758aa7.4be585","name":"","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":3660,"y":3480,"wires":[["b7fd9b1cfa901b50"]]},{"id":"25acf727c5e54ae2","type":"function","z":"14758aa7.4be585","name":"Format the header and payload","func":"msg.headers = {\n    \"Content-Type\": \"multipart/form-data; boundary=------------------------d74496d66958873e\",\n    \"User-Agent\": \"Fiddler\",\n    \"Host\": \"127.0.0.1\",\n    \"Cookie\": \"SID=nDRB9Afezq5ZvYyDAHLy7g6GRxFmQl0N\"//,\n    //\"Content-Length\": \"46075\"\n}\n\n\nmsg.payload = '--------------------------d74496d66958873e\\r\\n'+\n'Content-Disposition: form-data; name=\"torrents\"; filename=\"gimp-2.10.34-setup.exe.torrent\"\\r\\n'+\n'Content-Type: application/x-bittorrent\\r\\n'+\n'\\r\\n'+\nmsg.payload+'\\r\\n'+\n'--------------------------d74496d66958873e--\\r\\n';\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":3790,"y":3540,"wires":[["d2cfb5e94af20ee9"]]},{"id":"d2cfb5e94af20ee9","type":"http request","z":"14758aa7.4be585","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://ds1821:8083/api/v2/torrents/add","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"credentials":{},"x":4030,"y":3540,"wires":[["df7f51e66675b1e8"]]},{"id":"df7f51e66675b1e8","type":"debug","z":"14758aa7.4be585","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":4190,"y":3540,"wires":[]}]

Can anyone help me to understand what's going wrong here?

Copy the working postman as a cURL and well translate it for you into a flow.

curl --location --request POST 'http://ds1821:8083/api/v2/torrents/add' \ --header 'Cookie: SID=nDRB9Afezq5ZvYyDAHLy7g6GRxFmQl0N' \ --form 'torrents=@"/C:/Users/Tom/Desktop/autobrr/gimp-2.10.34-setup.exe.torrent"'

Thank you :slight_smile: Although perhaps I should point out my end goal is to retrieve the torrent from a URL rather than a local file, I was just using the local file to match up with the docs. I know I can just write the file from the URL before reading it as a local file, but I was hoping to keep it all in a single message.

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