Mojo::C...ltiPart(3)

πŸ’… Mojo::Content::MultiPart β€” like, the whole manual page, bestie

okay so welcome to Mojo::Content::MultiPart(3), from the User Contributed Perl Documentation ✨ this is genuinely one of my fave little container classes and I need you to be obsessed with it too, so let's go 🫢


🌸 NAME 🌸

Mojo::Content::MultiPart β€” HTTP multipart content. that's it, that's the vibe. it's a container, it holds other content, slay πŸ’…


✨ SYNOPSIS ✨

use Mojo::Content::MultiPart;

my $multi = Mojo::Content::MultiPart->new;
$multi->parse('Content-Type: multipart/mixed; boundary=---foobar');
my $single = $multi->parts->[4];

see that? you make one, you feed it a Content-Type with a boundary, and boom β€” you can reach into parts and grab part number [4]. iconic behaviour, no notes πŸ‘‘


πŸ¦‹ DESCRIPTION πŸ¦‹

Mojo::Content::MultiPart is literally just a container for HTTP multipart content πŸŽ€ and ngl it's built on some very serious specs, which is why it's so well-behaved:

like, it's giving "small class, huge standards energy" πŸ’œ


πŸ”₯ EVENTS πŸ”₯

okay so Mojo::Content::MultiPart inherits all events from Mojo::Content, plus it can emit this new one πŸ‘‡

🌈 part

$multi->on(part => sub ($multi, $single) {...});

Emitted when a new Mojo::Content::Single part starts ✨ (yes, starts β€” it fires as the part is beginning, not after. very "front row at the concert" of it).

here's the example, verbatim, because it's lowkey cute:

$multi->on(part => sub ($multi, $single) {
  return unless $single->headers->content_disposition =~ /name="([^"]+)"/;
  say "Field: $1";
});

so it bails unless the content_disposition matches that regex, then prints the captured name as Field: $1. chef's kiss πŸ“


πŸ’– ATTRIBUTES πŸ’–

Mojo::Content::MultiPart inherits all attributes from Mojo::Content and implements this new one:

πŸŽ€ parts

my $parts = $multi->parts;
$multi    = $multi->parts([Mojo::Content::Single->new]);

the content parts embedded in this multipart content β€” usually Mojo::Content::Single objects πŸ’… ("usually", bestie, not always, read the room)


πŸ‘‘ METHODS πŸ‘‘

Mojo::Content::MultiPart inherits all methods from Mojo::Content and implements these new ones:

πŸ’€ body_contains

my $bool = $multi->body_contains('foobarbaz');

check if the content parts contain a specific string. simple, useful, ate πŸ”₯

πŸ’€ body_size

my $size = $multi->body_size;

content size in bytes. that's the whole thing. numbers don't lie πŸ“

πŸ’€ build_boundary

my $boundary = $multi->build_boundary;

generate a suitable boundary for the content and add it to the "Content-Type" header πŸŽ€ it does the boring part so you don't have to, we love a main character who handles logistics.

πŸ’€ clone

my $clone = $multi->clone;

return a new Mojo::Content::MultiPart object cloned from this content if possible β€” otherwise it returns "undef" 😭 so like, check before you go using it, fr fr.

πŸ’€ get_body_chunk

my $bytes = $multi->get_body_chunk(0);

get a chunk of content starting from a specific position πŸ‘€

⚠️ heads up bestie: it might not be possible to get the same chunk twice if the content was generated dynamically. so don't be out here assuming chunks are re-readable, because sometimes they are simply not πŸ’€ that's not a bug, that's just how dynamic content works.

πŸ’€ is_multipart

my $bool = $multi->is_multipart;

True β€” this is a Mojo::Content::MultiPart object βœ… identity check, passed, glowing.

πŸ’€ new

my $multi = Mojo::Content::MultiPart->new;
my $multi
  = Mojo::Content::MultiPart->new(parts => [Mojo::Content::Single->new]);
my $multi
  = Mojo::Content::MultiPart->new({parts => [Mojo::Content::Single->new]});

construct a new Mojo::Content::MultiPart object β€” and it also subscribes to the event "read" in Mojo::Content with the default content parser 🫢 so yeah, three ways to call it, all valid, pick your fighter πŸ’…


🌟 SEE ALSO 🌟


okay that's the whole page, nothing skipped, nothing invented, every flag and method and caveat accounted for 🧚

sign-off time: this absolute gem of a doc shipped as perl v5.42.0, dated 2026-07-15 β€” so yeah, technically from the future, and honestly? it aged flawlessly πŸ‘‘πŸ’œ bye bestie, go build some multipart content πŸŽ€

πŸ“¦ where this page comes from