Typically most users will want to use handleFileUploads, which writes
uploaded files to a temporary directory before sending them on to a handler
specified by the user.

Users who wish to handle their file uploads differently can use the
lower-level streaming Iteratee interface called handleMultipart. That
function takes uploaded files and streams them to an Iteratee consumer of
the user's choosing.

Using these functions requires making "policy" decisions which Snap can't
really make for users, such as "what's the largest PDF file a user is
allowed to upload?" and "should we read form inputs into the parameters
mapping?". Policy is specified on a "global" basis (using
UploadPolicy), and on a per-file basis (using PartUploadPolicy, which
allows you to reject or limit the size of certain uploaded
Content-types).

Reads uploaded files into a temporary directory and calls a user handler
to process them.

Given a temporary directory, global and file-specific upload policies, and
a user handler, this function consumes a request body uploaded with
Content-type: multipart/form-data. Each file is read into the temporary
directory, and then a list of the uploaded files is passed to the user
handler. After the user handler runs (but before the Response body
Enumerator is streamed to the client), the files are deleted from disk;
so if you want to retain or use the uploaded files in the generated
response, you would need to move or otherwise process them.

The argument passed to the user handler is a list of:

(PartInfo, Either PolicyViolationException FilePath)

The first half of this tuple is a PartInfo, which contains the
information the client browser sent about the given upload part (like
filename, content-type, etc). The second half of this tuple is an Either
stipulating that either:

the file was rejected on a policy basis because of the provided
PartUploadPolicy handler

the file was accepted and exists at the given path.

If the request's Content-type was not "multipart/formdata", this
function skips processing using pass.

Given an upload policy and a function to consume uploaded "parts",
consume a request body uploaded with Content-type: multipart/form-data.
Normally most users will want to use handleFileUploads (which writes
uploaded files to a temporary directory and passes their names to a given
handler) rather than this function; the lower-level handleMultipart
function should be used if you want to stream uploaded files to your own
iteratee function.

If the request's Content-type was not "multipart/formdata", this
function skips processing using pass.

Policy

General upload policy

whether to treat parts without filenames as form input (reading them into
the rqParams map)

because form input is read into memory, the maximum size of a form input
read in this manner, and the maximum number of form inputs

the minimum upload rate a client must maintain before we kill the
connection; if very low-bitrate uploads were allowed then a Snap server
would be vulnerable to a trivial denial-of-service using a
"slowloris"-type attack

the minimum number of seconds which must elapse before we start killing
uploads for having too low an upload rate.

the amount of time we should wait before timing out the connection
whenever we receive input from the client.