HTTP request to express backend using Postman is throwing unexpected end of form (multipart form data)

Viewed 358

I am sending a multipart/form-data request to my API-backend(in google functions) using postman. In the request, I am sending two fields and one file. The request is processed by Multer/busboy, which throws the error - Unexpected end of the form. Here is my request from the postman in raw form:

POST /app/api/projects/newproject HTTP/1.1
Content-Type: multipart/form-data; boundary=XXX
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: a339b8c1-caa3-4629-8adf-d20967f84
Host: my-projectxxx.cloudfunctions.net
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: connect.sid=s%3A3h93yTISWRf4cibUG-8Ra3HpqV_iznVz.GhVvgAynx1RuwTyzjCCAlb%2FspGgTzf%2F%2F6VJrkGvNJ
Content-Length: 718115
 
--XXX
Content-Disposition: form-data; name="file"; filename="aliens.png"
Content-Type: image/png
<aliens.png>
--XXX
Content-Disposition: form-data; name="name"
Content-Type: text
John
--XXX
Content-Disposition: form-data; name="is_photo_changed"
Content-Type: text
1
--XXX--
 
HTTP/1.1 500 Internal Server Error
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:3000
content-security-policy: default-src 'none'

And here is the error recorded in my API-backend log:

Unexpected end of form at Multipart._final (/workspace/node_modules/busboy/lib/types/multipart.js:588:17) at callFinal (node:internal/streams/writable:694:27) at prefinish (node:internal/streams/writable:723:7) at finishMaybe (node:internal/streams/writable:733:5) at Multipart.Writable.end (node:internal/streams/writable:631:5) at onend (node:internal/streams/readable:693:10) at processTicksAndRejections (node:internal/process/task_queues:78:11)

It works in the local run but throws an error after being deployed and used in google cloud functions. Any issue with the request? ANy alternative of the postman to test?

1 Answers

There must be an empty line between the headers and the content, for example:

--XXX
Content-Disposition: form-data; name="name"
Content-Type: text

John
--XXX

And the lines in the multipart request body must end with CRLF, not just LF.

The following code demonstrates this:

express().post("/", multer().fields([]), function(req, res) {
  res.json(req.body);
})
.listen(80, function() {
  http.request("http://localhost", {
    method: "POST",
    headers: {"Content-Type": "multipart/form-data;boundary=XXX"}
  }).end(`--XXX
Content-Disposition: form-data; name="name"
Content-Type: text

John
--XXX--`.replace(/\n/g,"\r\n"))
  .on("response", function(r) {
    r.pipe(process.stdout);
  });
});

Removing the empty line before John or removing the .replace leads to "Unexpected end of form" errors in multer.

Related