Know-How für Ihr Projekt

Perl Documentation


parse_post_data - Parse the body of a POST request


    # This can be enabled server-wide or for specific <Location> sections.
    Plugin parse_post_data

    <Location /upload-form>
        # Each section can have individual options.
        AllowFileUploads 5
    # [...]

And in your plugin:

my $value = $client->param('foo');


By default AxKit2 does not process POST data, leaving this entirely up to the plugin to do that if it so requires. This plugin parses POST form data and places that data in the client's param() API.

Both standard content types (application/x-www-form-urlencoded and multipart/form-data) are supported, including file uploads.

File uploads are stored as hash references with the following fields:

* tmpname is the local file name of the temporary file containing upload data. It includes a decently guessed file extension.

* filename is the file name as sent by the user-agent.

* type is the content-type as sent by the user-agent. Note that this value is more reliable than checking the file extension of filename. Unknown/unspecified file content is tagged as "application/octet-stream", but if you have File::MMagic installed, it will be used to guess the correct type in those cases.

* fh is an open file handle for upload data. You can start reading from it immediately.

* size is the uploaded file size.

Note that file uploads are disabled by default due to security reasons (see next section).

Temporary files used by file uploads usually don't need any special treatment, this plugin cares about removing them when appropriate. If you want files to stay, move (rename) them somewhere else. See FileUploadTempDir below.

Another thing to mind are encodings: POST data often doesn't come with charset information. Thus, no attempt is made to process or normalize data. What you'll get are byte strings, not perl unicode strings. This can easily lead to undesired results if non-ASCII charaters are used. See AxKit2::Utils::ustr for a useful utility for these cases.


Since POST requests can potentially take up a lot of memory and disk space, there are several security options available to limit the amount of damage that can be done involuntarily:

* No files larger than FileSizeLimit will be created. It will indirectly limit possible memory impact of subsequent processing plugins, so it's just a safeguard against sloppy programming. If you're checking file sizes anyways later on, you can set this to BodySizeLimit.

* No requests larger than BodySizeLimit are accepted. This prevents users from accidentally uploading a bunch of dreaded full-page 1200 DPI scans in BMP format ;)

* No requests that have more than BodyMemLimit of plain form data (i.e., not files) are accepted. That way, misconfigured user-agents are caught. Set this to the largest value your forms can yield.

Don't set these limits too low, since clients will be shut out with a plain 403 FORBIDDEN message. If you need more user-friendly error messages, set FileSizeLimit as suggested above and manually check for your desired file size limit.

While these options make it easy to make the server resilient to accidental fumbles, to make the server really tamper-proof you need to select limits more carefully:

* Maximum disk space consumed by temporary files is BodySizeLimit*AllowFileUploads.

* Maximum main memory per request is BodyMemLimit plus whatever a normal request uses. This plugin does not limit the number of simultaneous requests in general, so that must be taken care of somewhere else. It is strongly recommended (and most efficient) to use OS resource limits, but you already do that anyways, right? ;)

Note that file types are inherently unreliable. The browser may send wrong or unknown content types, so always handle unexpected/invalid content gracefully.


BodySizeLimit size

Specify maximum size for POST data, regardless of encoding. Request bodies larger than this will yield a 403 status code (FORBIDDEN). Note that this includes protocol overhead, so the maximum size of actually uploaded data will be slightly smaller.

Default value is 128KiB, suitable for most POST forms without files.

AllowFileUploads COUNT

Enable processing of uploaded files. This will lead to temporary files being created. If disabled (the default), HTML forms with enctype="multipart/form-data" will still work, but a 403 FORBIDDEN will result if a file upload is encountered.

The value is not a boolean, but an integer value, the number of simultaneous requests allowed to upload files. This allows you to limit the total possible disk usage.

You probably also want to increase BodySizeLimit.

BodyMemLimit size

Specify maximum memory size for form field values. This option limits the amount of main memory a single request can use. It does not count file uploads, as these are stored in temporary files.

Requests that result in field values with a total size larger than this will yield a 403 status code (FORBIDDEN).

Default value is 128KiB, suitable for most applications.

FileSizeLimit size

Specify maximum size for individual files. Since some common file operations (e.g., image manipulation) operate on a file loaded into memory, this option allows to limit the size of each uploaded file so that such file operations won't cause excessive memory usage. Uploading files larger than this will yield a 403 status code (FORBIDDEN). Note that BodySizeLimit still applies, so the largest file you can upload is min(FileSizeLimit,BodySizeLimit).

Default value is 4MiB, suitable for most image files.

FileUploadTempDir directory

Configure the temporary directory used for file uploads. Default is your OS temporary directory. If you intend to store files on disk anyways, it is recommended to set this to a private directory on the same disk volume as the final destination directory. That way, you won't have to copy the file, a simple and fast rename() will suffice.