Plack::Util(3)
π Plack::Util π
okay bestie, welcome to Plack::Util(3), part of the User Contributed Perl Documentation situation. this is the little grab-bag of helper subroutines that Plack uses, and that you (yes YOU, a Plack server dev or a framework dev) get to use too. it's giving toolbox. it's giving "here's some utilities so you don't have to write them yourself." let's get into it π
β¨ NAME β¨
Plack::Util β utility subroutines for Plack server and framework developers π«Ά
πΈ FUNCTIONS πΈ
π TRUE, FALSE
my $true = Plack::Util::TRUE;
my $false = Plack::Util::FALSE;
utility constants you include when you're setting boolean variables in the $env hash (like psgi.multithread, iykyk). they're constants, they're handy, they're literally just true and false. periodt β¨
π¦ load_class
my $class = Plack::Util::load_class($class [, $prefix ]);
it constructs a class name and then requires that class. if the .pm file for the class is not found, it throws an exception β exactly like the built-in require does. no cap.
if $prefix is set, the class name gets prepended to $class... UNLESS $class starts with a + sign, because that means the class name is already fully qualified bestie, we don't need to touch it.
my $class = Plack::Util::load_class("Foo"); # Foo
my $class = Plack::Util::load_class("Baz", "Foo::Bar"); # Foo::Bar::Baz
my $class = Plack::Util::load_class("+XYZ::ZZZ", "Foo::Bar"); # XYZ::ZZZ
β οΈ okay important !!! this function does not validate (or "sanitize") the string you pass it. so if you pass user input into this function β which is an insecure thing to do in the first place, like genuinely, don't β it might lead to unexpected behavior of loading files outside your@INCpath. π if you want a generic module loading function, go check out CPAN modules such asModule::Runtime. slay responsibly π
π§ is_real_fh
if ( Plack::Util::is_real_fh($fh) ) { }
returns true if the given $fh is a real file handle that has a file descriptor. it returns false if $fh is a PerlIO handle that isn't really related to the underlying file, etc. that's the vibe check β¨
π content_length
my $cl = Plack::Util::content_length($body);
returns the length of the content from body, if it can be calculated at all. if $body is an array ref, it's a sum of the length of each chunk. if $body is a real filehandle, it's the remaining size of the filehandle. otherwise it just returns undef. no notes π
π set_io_path
Plack::Util::set_io_path($fh, "/path/to/foobar.txt");
sets the (absolute) file path to the $fh filehandle object, so you can call $fh->path on it. as a side effect, $fh gets blessed to an internal package β but it can still be treated as a normal file handle, so don't panic.
this module doesn't normalize or absolutize the given path, and it's intended to be used from Server or Middleware implementations. see also IO::File::WithPath. obsessed π«Ά
β foreach
Plack::Util::foreach($body, $cb);
iterates through $body (which is an array reference or an IO::Handle-like object) and passes each line to the callback function. and when we say "line" β it is NOT really guaranteed to be a line. just so you know π
internally it sets the buffer length $/ to 65536 in case it reads the binary file, unless otherwise set in the caller's code. iconic behavior fr fr.
π load_psgi
my $app = Plack::Util::load_psgi $psgi_file_or_class;
loads an app.psgi file or a class name (like MyApp::PSGI) and requires the file to get the PSGI application handler. if the file can't be loaded β like, file doesn't exist, or it has a perl syntax error β it will throw an exception. rude but fair.
since version 1.0006, this function would not load PSGI files from include paths (@INC) unless it looks like a class name that only consists of [A-Za-z0-9_:]. for example:
Plack::Util::load_psgi("app.psgi"); # ./app.psgi
Plack::Util::load_psgi("/path/to/app.psgi"); # /path/to/app.psgi
Plack::Util::load_psgi("MyApp::PSGI"); # MyApp/PSGI.pm from @INC
π¨ Security: if you give this function a class name or module name that is loadable from your system, it will load the module. this could lead to a security hole:perl my $psgi = ...; # user-input: consider "Moose" $app = Plack::Util::load_psgi($psgi); # this would lead to 'require "Moose.pm"'!generally speaking, passing external input to this function is considered very insecure. if you really want to do that, validate that the given file name contains dots (likefoo.psgi) and also turn it into a full path in your caller's code. please, for me π
π run_app
my $res = Plack::Util::run_app $app, $env;
runs the $app by wrapping errors with eval, and if an error is found, it logs it to $env->{'psgi.errors'} and returns the template 500 Error response. it's giving safety net π«Ά
β¨ header_get, header_exists, header_set, header_push, header_remove β¨
my $hdrs = [ 'Content-Type' => 'text/plain' ];
my $v = Plack::Util::header_get($hdrs, $key); # First found only
my @v = Plack::Util::header_get($hdrs, $key);
my $bool = Plack::Util::header_exists($hdrs, $key);
Plack::Util::header_set($hdrs, $key, $val); # overwrites existent header
Plack::Util::header_push($hdrs, $key, $val);
Plack::Util::header_remove($hdrs, $key);
utility functions to manipulate a PSGI response headers array reference. the methods that read an existent header value handle the header name as case insensitive. so yes, casing does not matter, we are all equals here π
my $hdrs = [ 'Content-Type' => 'text/plain' ];
my $v = Plack::Util::header_get($hdrs, 'content-type'); # 'text/plain'
π headers
my $headers = [ 'Content-Type' => 'text/plain' ];
my $h = Plack::Util::headers($headers);
$h->get($key);
if ($h->exists($key)) { ... }
$h->set($key => $val);
$h->push($key => $val);
$h->remove($key);
$h->headers; # same reference as $headers
give it a header array reference and it returns a convenient object that has instance methods to access the header_* functions with an OO interface. the object holds a reference to the original $headers argument you gave it, and updates that reference accordingly when you call write methods like set, push or remove. it also has a headers method that would return the same reference. main character energy, honestly π
πΈ status_with_no_entity_body
if (status_with_no_entity_body($res->[0])) { }
returns true if the given status code doesn't have any Entity body in the HTTP response β i.e. it's 100, 101, 204 or 304. that's it, that's the whole function, and it ate π
π¦ inline_object
my $o = Plack::Util::inline_object(
write => sub { $h->push_write(@_) },
close => sub { $h->push_shutdown },
);
$o->write(@stuff);
$o->close;
creates an instant object that can react to methods passed in the constructor. super handy when you need to create an IO stream object for input or errors. literally so convenient π«Ά
π§ encode_html
my $encoded_string = Plack::Util::encode_html( $string );
entity encodes <, >, &, " and ' in the input string and returns it. all the scary characters, handled β¨
π response_cb
see "RESPONSE CALLBACK" in Plack::Middleware for details. go read that one bestie, i promise it's worth it π
okay that's the whole page!! this was Plack::Util(3), from the User Contributed Perl Documentation, and the footer says it's perl v5.42.3 dated 2026-10-18 β so yeah, we're on some fresh-from-the-future energy. go write a PSGI app, you're gonna slay ππβ¨
π¦ where this page comes from
- fedora 43: perl-Plack 1.0055-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-Plack 1.0055-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms