Deviopath › Node.js

Multipart Form Parser

Hard · Parsing

HTML forms with file uploads send multipart/form-data, which packages like multer and busboy parse in Node. The body is made of parts separated by a boundary string chosen by the browser (it is in the Content-Type header, for example multipart/form-data; boundary=XyZ).

Write parseMultipart(body, boundary) for a simplified, text-only version. All line breaks are \r\n.

- The first delimiter is --<boundary>, either at the very start of the body or at the start of a line. Text before it (the preamble) is ignored.

- Every later delimiter is \r\n--<boundary>: the \r\n in front belongs to the delimiter, not to the content. The closing delimiter is --<boundary>--, and everything after it (the epilogue) is ignored.

- After a normal delimiter comes \r\n, then the part: header lines, an empty line, then the content up to the next delimiter.

- Header names are case-insensitive and values are trimmed. Content-Disposition looks like form-data; name="field"; filename="a.txt". Parameter names are case-insensitive. A parameter value is either quoted (it may contain ; and spaces, and \" stands for a quote) or a plain token without spaces or ;.

- A part with a filename parameter (even an empty one) is a file: add { field, filename, contentType, content } to files. contentType comes from the part's Content-Type header and defaults to "text/plain" (the default in RFC 7578).

- Other parts are fields: fields[name] = content. If the same name appears again, the value becomes an array of all its values in order. Parts without a name are skipped.

- If the closing delimiter is missing, or a delimiter is followed by something other than \r\n or --, return { error: "Unexpected end of form" }.

Otherwise return { fields, files }.

Next: In-Memory fs With Real Error Codes