Accessing multipart form data
Multipart Entry
Preliminaries
This note describes the properties of a single entry within a multipart/form-data payload.
A workOrder's _multipartFormData
property is an array of MultipartEntry
objects, one for each section of the multipart/form-data payload.
These objects are parsed from the requestBody by the server. Here is what they look like, in a nutshell:
MultipartEntry {
// parsing privates
startsAt
endsAt
dataStartsAt
dataEndsAt
// parsing intermediates
contentDisposition
contentType
// public data
name
filename
mimeType
charset
data
dataLength
// response
httpStatus
}
The rest of this note provides details useful to anyone working with multipart/form-data.
HTML forms
Each multipart entry carries the value of one HTML form input element. Elements of type=file
are binary Buffers holding the full contents of a file. Elements of type=text
, and other textual inputs, are simple string values.
Here is a sample HTML page that will trigger the creation of multipartEntries:
<html>
<form enctype='multipart/form-data' method=post action='/upload-pics'>
<input name=pictureDesc type=text>
<input name=pictureFile type=file>
<input type=submit value=Submit>
</form>
</html>
Parsing privates
The server is responsible for parsing internal multipart payloads into userland entries. This occurs before any plugin is invoked.
Several private variables are used in this process: startsAt
and endsAt
define the offset, into the requestBodyBytes, of the localBuffer for the section.
The dataStartsAt
and dataEndsAt
variables define the offset into that localBuffer of the payload itself, excluding any headers.
Parsing intermediates
Each multipart consists of headers and payload. Two headers are allowed by the IETF RFC 7578 spec: content-disposition
(which is required) and content-type
(which is optional).
contentDisposition
This holds the full text of the content-disposition
header for this entry. It will contain these subparts:
form-data
: a string identifier confirming that this is multipart data.name
: the text value of the "name" assigned to the HTML form'sinput
element by the web page developer.filename
: the name of the file, without leading directory path, of the file being uploaded. This is optional and omitted when the payload is not a file, but from an input elementtype=text
.
contentType
When present, it will contain the full text of the content-type
header for this entry. It is a mime type, plus an optional charset value.
Public data
name
A string value extracted from the content-disposition
header containing the "name" attribute of the HTML form's input
element.
filename
A string value extracted from the content-disposition
header containing the base filename of the file being uploaded. It does not include any path directory.
This will be an empty string if the multipart is from an HTML input element that is not type=file
.
mimeType
The mime type of the file, as determined by the browser. This will be an empty string if the multipart is not a file.
charset
The character set encoding of the file. Assumed to be UTF-8 for any "text" mime type, and BINARY for anything else (image/png, image/jpeg, etc.).
data
A Buffer object containing the file's contents. For safe access, use the binary accessor dataBytes
or the string accessor dataStr
.
dataBytes
Provides safe access to the entry's data Buffer.
dataStr
Converts the entry's data Buffer to a string using the value of the charset
property.
dataLength
The length of the data Buffer, in bytes.
Response
httpStatus
This property is not set by the server. It may be used by plugins to set the httpStatus of the operation being performed for the user.
This can be used, for example, when the overall HTTP response status code is 207 "Multi Status", and the response payload is a JSON object containing the separate response codes for each file being uploaded.
Review
Key points for successfully using multipartEntry objects:
- Multipart form data may be used to safely transfer binary resources (images, PDFs, data) to the server.
- Access to the underlying binary Buffer is through the
dataBytes
property. - Access to text data is through the
dataStr
property.