File: //usr/local/share/man/man3/Plack::Util.3pm
.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Plack::Util 3"
.TH Plack::Util 3 "2020-11-30" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Plack::Util \- Utility subroutines for Plack server and framework developers
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
.IP "\s-1TRUE, FALSE\s0" 4
.IX Item "TRUE, FALSE"
.Vb 2
\& my $true = Plack::Util::TRUE;
\& my $false = Plack::Util::FALSE;
.Ve
.Sp
Utility constants to include when you specify boolean variables in \f(CW$env\fR hash (e.g. \f(CW\*(C`psgi.multithread\*(C'\fR).
.IP "load_class" 4
.IX Item "load_class"
.Vb 1
\& my $class = Plack::Util::load_class($class [, $prefix ]);
.Ve
.Sp
Constructs a class name and \f(CW\*(C`require\*(C'\fR the class. Throws an exception
if the .pm file for the class is not found, just with the built-in
\&\f(CW\*(C`require\*(C'\fR.
.Sp
If \f(CW$prefix\fR is set, the class name is prepended to the \f(CW$class\fR
unless \f(CW$class\fR begins with \f(CW\*(C`+\*(C'\fR sign, which means the class name is
already fully qualified.
.Sp
.Vb 3
\& 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
.Ve
.Sp
Note that this function doesn't validate (or \*(L"sanitize\*(R") the passed
string, hence if you pass a user input to this function (which is an
insecure thing to do in the first place) it might lead to unexpected
behavior of loading files outside your \f(CW@INC\fR path. If you want a
generic module loading function, you should check out \s-1CPAN\s0 modules
such as Module::Runtime.
.IP "is_real_fh" 4
.IX Item "is_real_fh"
.Vb 1
\& if ( Plack::Util::is_real_fh($fh) ) { }
.Ve
.Sp
returns true if a given \f(CW$fh\fR is a real file handle that has a file
descriptor. It returns false if \f(CW$fh\fR is PerlIO handle that is not
really related to the underlying file etc.
.IP "content_length" 4
.IX Item "content_length"
.Vb 1
\& my $cl = Plack::Util::content_length($body);
.Ve
.Sp
Returns the length of content from body if it can be calculated. If
\&\f(CW$body\fR is an array ref it's a sum of length of each chunk, if
\&\f(CW$body\fR is a real filehandle it's a remaining size of the filehandle,
otherwise returns undef.
.IP "set_io_path" 4
.IX Item "set_io_path"
.Vb 1
\& Plack::Util::set_io_path($fh, "/path/to/foobar.txt");
.Ve
.Sp
Sets the (absolute) file path to \f(CW$fh\fR filehandle object, so you can
call \f(CW\*(C`$fh\->path\*(C'\fR on it. As a side effect \f(CW$fh\fR is blessed to an
internal package but it can still be treated as a normal file
handle.
.Sp
This module doesn't normalize or absolutize the given path, and is
intended to be used from Server or Middleware implementations. See
also IO::File::WithPath.
.IP "foreach" 4
.IX Item "foreach"
.Vb 1
\& Plack::Util::foreach($body, $cb);
.Ve
.Sp
Iterate through \fI\f(CI$body\fI\fR which is an array reference or
IO::Handle\-like object and pass each line (which is \s-1NOT\s0 really
guaranteed to be a \fIline\fR) to the callback function.
.Sp
It internally sets the buffer length \f(CW$/\fR to 65536 in case it reads
the binary file, unless otherwise set in the caller's code.
.IP "load_psgi" 4
.IX Item "load_psgi"
.Vb 1
\& my $app = Plack::Util::load_psgi $psgi_file_or_class;
.Ve
.Sp
Load \f(CW\*(C`app.psgi\*(C'\fR file or a class name (like \f(CW\*(C`MyApp::PSGI\*(C'\fR) and
require the file to get \s-1PSGI\s0 application handler. If the file can't be
loaded (e.g. file doesn't exist or has a perl syntax error), it will
throw an exception.
.Sp
Since version 1.0006, this function would not load \s-1PSGI\s0 files from
include paths (\f(CW@INC\fR) unless it looks like a class name that only
consists of \f(CW\*(C`[A\-Za\-z0\-9_:]\*(C'\fR. For example:
.Sp
.Vb 3
\& 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
.Ve
.Sp
\&\fBSecurity\fR: 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:
.Sp
.Vb 2
\& my $psgi = ...; # user\-input: consider "Moose"
\& $app = Plack::Util::load_psgi($psgi); # this would lead to \*(Aqrequire "Moose.pm"\*(Aq!
.Ve
.Sp
Generally speaking, passing an external input to this function is
considered very insecure. If you really want to do that, validate that
a given file name contains dots (like \f(CW\*(C`foo.psgi\*(C'\fR) and also turn it
into a full path in your caller's code.
.IP "run_app" 4
.IX Item "run_app"
.Vb 1
\& my $res = Plack::Util::run_app $app, $env;
.Ve
.Sp
Runs the \fI\f(CI$app\fI\fR by wrapping errors with \fIeval\fR and if an error is
found, logs it to \f(CW\*(C`$env\->{\*(Aqpsgi.errors\*(Aq}\*(C'\fR and returns the
template 500 Error response.
.IP "header_get, header_exists, header_set, header_push, header_remove" 4
.IX Item "header_get, header_exists, header_set, header_push, header_remove"
.Vb 1
\& my $hdrs = [ \*(AqContent\-Type\*(Aq => \*(Aqtext/plain\*(Aq ];
\&
\& 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);
.Ve
.Sp
Utility functions to manipulate \s-1PSGI\s0 response headers array
reference. The methods that read existent header value handles header
name as case insensitive.
.Sp
.Vb 2
\& my $hdrs = [ \*(AqContent\-Type\*(Aq => \*(Aqtext/plain\*(Aq ];
\& my $v = Plack::Util::header_get($hdrs, \*(Aqcontent\-type\*(Aq); # \*(Aqtext/plain\*(Aq
.Ve
.IP "headers" 4
.IX Item "headers"
.Vb 1
\& my $headers = [ \*(AqContent\-Type\*(Aq => \*(Aqtext/plain\*(Aq ];
\&
\& 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
.Ve
.Sp
Given a header array reference, returns a convenient object that has
an instance methods to access \f(CW\*(C`header_*\*(C'\fR functions with an \s-1OO\s0
interface. The object holds a reference to the original given
\&\f(CW$headers\fR argument and updates the reference accordingly when called
write methods like \f(CW\*(C`set\*(C'\fR, \f(CW\*(C`push\*(C'\fR or \f(CW\*(C`remove\*(C'\fR. It also has \f(CW\*(C`headers\*(C'\fR
method that would return the same reference.
.IP "status_with_no_entity_body" 4
.IX Item "status_with_no_entity_body"
.Vb 1
\& if (status_with_no_entity_body($res\->[0])) { }
.Ve
.Sp
Returns true if the given status code doesn't have any Entity body in
\&\s-1HTTP\s0 response, i.e. it's 100, 101, 204 or 304.
.IP "inline_object" 4
.IX Item "inline_object"
.Vb 6
\& my $o = Plack::Util::inline_object(
\& write => sub { $h\->push_write(@_) },
\& close => sub { $h\->push_shutdown },
\& );
\& $o\->write(@stuff);
\& $o\->close;
.Ve
.Sp
Creates an instant object that can react to methods passed in the
constructor. Handy to create when you need to create an \s-1IO\s0 stream
object for input or errors.
.IP "encode_html" 4
.IX Item "encode_html"
.Vb 1
\& my $encoded_string = Plack::Util::encode_html( $string );
.Ve
.Sp
Entity encodes \f(CW\*(C`<\*(C'\fR, \f(CW\*(C`>\*(C'\fR, \f(CW\*(C`&\*(C'\fR, \f(CW\*(C`"\*(C'\fR and \f(CW\*(C`\*(Aq\*(C'\fR in the input string
and returns it.
.IP "response_cb" 4
.IX Item "response_cb"
See \*(L"\s-1RESPONSE CALLBACK\*(R"\s0 in Plack::Middleware for details.