NAME
Punk::Upload - an uploaded file from a multipart form
SYNOPSIS
post '/avatar' => sub {
my ($c) = @_;
my $up = $c->req->upload('avatar') or return $c->text('no file', 400);
$up->save("/var/uploads/" . $up->filename);
$c->json({ name => $up->filename, bytes => $up->size });
};
DESCRIPTION
A file part of a multipart/form-data request. $c->req->form parses the body once: ordinary fields become parameters ($c->param), and file parts become Punk::Upload objects reachable through $c->req->upload($name) (or $c->upload($name)) and $c->req->uploads. A field uploaded more than once yields an arrayref from uploads; upload gives the first.
The bytes are held in memory in this cut - bound your request body size accordingly; a tempfile-backed mode for large uploads is a follow-on.
METHODS
filename
The client-supplied file name (do not trust it as a path).
name
The form field name.
type
The part's Content-Type (application/octet-stream if the client sent none).
size
The byte length.
content
The uploaded bytes.
save($path)
Write the bytes to $path. Croaks if it cannot open the file.
Note what this is not: the bytes were already resident before the handler ran, so this is a write, not a stream. ->save does not reduce the memory an upload costs; it only puts a copy on disk.
SIZE, HONESTLY
An upload arrives whole, in memory, twice over - once in the server's read buffer and again as the decoded part - before a handler sees it. So:
the practical maximum is the server's request ceiling, which for Hyperman is
max_bodyand defaults to 16MBraising that ceiling raises a worker's worst-case resident size in proportion: roughly
workers x max_body x concurrent uploads per worker"max_body" in Punk does not help here. It refuses an oversize request after the bytes have arrived, which saves the parse and the handler but not the memory
For genuinely large uploads, terminate them at a proxy or hand the client a pre-signed direct-to-storage URL and take only the resulting key. Raising a server ceiling to a gigabyte to accept gigabyte uploads does work, and costs a gigabyte per concurrent upload per worker.
SEE ALSO
Punk, "upload" in Punk::Request, "max_body" in Punk, "max_body: the request ceiling" in Hyperman.
AUTHOR
LNATION <email@lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION <email@lnation.org>.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)