HTTP::...Parser(3pm)
π HTTP::...Parser(3pm) β like, the whole manual, but make it make sense
Okay bestie, so this is the man page for HTTP::Entity::Parser (perl, section 3pm), and I'm gonna walk you through it like we're texting at 2am. Grab a π snack, this is gonna slay.
β¨ NAME β¨
HTTP::Entity::Parser β PSGI compliant HTTP Entity Parser. That's it, that's the whole vibe. It parses HTTP entities, and it plays nice with PSGI. π
πΈ SYNOPSIS πΈ
Here's the little intro snippet, copy it exactly, no cap:
use HTTP::Entity::Parser;
my $parser = HTTP::Entity::Parser->new;
$parser->register('application/x-www-form-urlencoded','HTTP::Entity::Parser::UrlEncoded');
$parser->register('multipart/form-data','HTTP::Entity::Parser::MultiPart');
$parser->register('application/json','HTTP::Entity::Parser::JSON');
sub app {
my $env = shift;
my ( $params, $uploads) = $parser->parse($env);
}
That's the whole glow-up in five lines π
π¦ DESCRIPTION π¦
So HTTP::Entity::Parser is a PSGI-compliant HTTP Entity parser, fr fr. And here's the cute part β it's also compatible with HTTP::Body π«Ά
But unlike HTTP::Body, this one reads HTTP entities straight out of PSGI's environment, specifically $env->{'psgi.input'}, and parses that. No middleman, no drama. β¨
And what formats does it support? I'm so glad you asked:
application/x-www-form-urlencodedmultipart/form-dataapplication/json
Three icons, all serving π
π METHODS π
new( buffer_length => $length:Intger)
Creates the instance. Baby's first parser β¨
buffer_length
The buffer length that HTTP::Entity::Parser reads from psgi.input. Default is 16384. That's the number, don't come for me. π
register($content_type:String, $class:String, $opts:HashRef)
Registers a parser class. You literally just hand it a content type and a class and it's like "say less" π₯
$parser->register('application/x-www-form-urlencoded','HTTP::Entity::Parser::UrlEncoded');
$parser->register('multipart/form-data','HTTP::Entity::Parser::MultiPart');
$parser->register('application/json','HTTP::Entity::Parser::JSON');
If the request's content_type matches a registered type, HTTP::Entity::Parser uses the registered parser class. Iconic matching behaviour tbh.
And if content_type does not match any registered type? HTTP::Entity::Parser::OctetStream gets used. It's the default bestie, always showing up for you π«Ά
parse($env:HashRef)
Parses HTTP entities from PSGI's env. The main character method, lowkey π
my ( $params:ArrayRef, $uploads:ArrayRef) = $parser->parse($env);
$param is a key-value pair list. (Yes, the doc says $param there, and the examples say $params β I'm just relaying the messages, don't shoot the messenger π)
my ( $params, $uploads) = $parser->parse($env);
my $body_parameters = Hash::MultiValue->new(@$params);
$uploads is an ArrayRef of HashRef. And the shape of one of those hashrefs is chef's kiss, look:
my ( $params, $uploads) = $parser->parse($env);
warn Dumper($uploads->[0]);
{
"name" => "upload", #field name
"headers" => [
"Content-Type" => "application/octet-stream",
"Content-Disposition" => "form-data; name=\"upload\"; filename=\"hello.pl\""
],
"size" => 78, #size of upload content
"filename" => "hello.png", #original filename in the client
"tempname" => "/tmp/XXXXX", # path to the temporary file where uploaded file is saved
}
Every key got a lil comment explaining itself, we love a self-documenting hash. π§
And when you use it with Plack::Request::Upload, it goes a little like this:
my ( $params, $uploads) = $parser->parse($env);
my $upload_hmv = Hash::MultiValue->new();
while ( my ($k,$v) = splice @$uploads, 0, 2 ) {
my %copy = %$v;
$copy{headers} = HTTP::Headers::Fast->new(@{$v->{headers}});
$upload_hmv->add($k, Plack::Request::Upload->new(%copy));
}
(Yes I kept the indentation exactly as the original had it. Fidelity queen. π )
π PARSERS π
Here's the whole squad, one by one:
- OctetStream β the default parser. This one does not parse the entity, and always returns an empty list. It's the "I'm just here" parser and honestly? Respect. π
- UrlEncoded β for
application/x-www-form-urlencoded. It's used for HTTP POST without file upload. Simple, effective, ate. β - MultiPart β for
multipart/form-data. It's used for HTTP POST that contains file upload. Big upload energy.
The MultiPart parser uses HTTP::MultiPartParser. π§
- JSON β for
application/json. This parser decodes the JSON body automatically. And ngl, it's genuinely convenient to use with Ajax forms. Obsessed. π₯
π WHAT'S DIFFERENT FROM HTTP::Body π
Okay so the whole "why is this a separate module" tea:
HTTP::Entity::Parseraccepts PSGI's env and reads the body from it. πΈHTTP::Entity::Parseris able to choose parsers by the instance β meanwhileHTTP::Bodyrequires you to modify global variables π which, yeah, no thank you.
That's the difference. Periodt. π
π SEE ALSO π
Go check these out, they're all in the group chat:
HTTP::BodyHTTP::MultiPartParserPlack::RequestWWW::Form::UrlEncodedβHTTP::Entity::Parseruses this for parsingapplication/x-www-form-urlencoded. iykyk π
π LICENSE π
Copyright (C) Masahiro Nagano.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. π«Ά
π AUTHOR π
- Masahiro Nagano
<kazeburo@gmail.com> - Tokuhiro Matsuno
<tokuhirom@gmail.com>
This module is based on tokuhirom's code, see <https://github.com/plack/Plack/pull/434> β¨
Okay so real talk: this whole page is from perl v5.42.0, dated 2020-11-29 β that's the version and date, and yes I'm mentioning them because the footer said so, and because we respect the metadata in this house πβ¨
Stay parsed, bestie π π¦πΈ
π¦ where this page comes from
- opensuse-leap 16.0: perl-HTTP-Entity-Parser 0.25-bp160.1.12 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms