.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.26) .\" .\" 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" '' '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 turned on, 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. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Plack::Middleware 3pm" .TH Plack::Middleware 3pm "2014-04-05" "perl v5.14.2" "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::Middleware \- Base class for easy\-to\-use PSGI middleware .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& package Plack::Middleware::Foo; \& use parent qw( Plack::Middleware ); \& \& sub call { \& my($self, $env) = @_; \& # Do something with $env \& \& # $self\->app is the original app \& my $res = $self\->app\->($env); \& \& # Do something with $res \& return $res; \& } \& \& # then in app.psgi \& use Plack::Builder; \& \& my $app = sub { ... } # as usual \& \& builder { \& enable "Plack::Middleware::Foo"; \& enable "Plack::Middleware::Bar", %options; \& $app; \& }; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Plack::Middleware is a utility base class to write \s-1PSGI\s0 middleware. All you have to do is to inherit from Plack::Middleware and then implement the callback \f(CW\*(C`call\*(C'\fR method (or the \f(CW\*(C`to_app\*(C'\fR method that would return the \s-1PSGI\s0 code reference) to do the actual work. You can use \f(CW\*(C`$self\->app\*(C'\fR to call the original (wrapped) application. .PP Your middleware object is created at the \s-1PSGI\s0 application compile time and is persistent during the web server life cycle (unless it is a non-persistent environment such as \s-1CGI\s0), so you should never set or cache per-request data like \f(CW$env\fR in your middleware object. See also \*(L"\s-1OBJECT\s0 \s-1LIFECYCLE\s0\*(R" in Plack::Component. .PP See Plack::Builder how to actually enable middleware in your \&\fI.psgi\fR application file using the \s-1DSL\s0. If you do not like our builder \s-1DSL\s0, you can also use the \f(CW\*(C`wrap\*(C'\fR method to wrap your application with a middleware: .PP .Vb 1 \& use Plack::Middleware::Foo; \& \& my $app = sub { ... }; \& $app = Plack::Middleware::Foo\->wrap($app, %options); \& $app = Plack::Middleware::Bar\->wrap($app, %options); .Ve .SH "RESPONSE CALLBACK" .IX Header "RESPONSE CALLBACK" The typical middleware is written like this: .PP .Vb 2 \& package Plack::Middleware::Something; \& use parent qw(Plack::Middleware); \& \& sub call { \& my($self, $env) = @_; \& # pre\-processing $env \& my $res = $self\->app\->($env); \& # post\-processing $res \& return $res; \& } .Ve .PP The tricky thing about post-processing the response is that it could either be an immediate 3 element array ref, or a code reference that implements the delayed (streaming) interface. .PP Dealing with these two types of response in each piece of middleware is pointless, so you're recommended to use the \f(CW\*(C`response_cb\*(C'\fR wrapper function in Plack::Util when implementing a post processing middleware. .PP .Vb 5 \& my $res = $app\->($env); \& Plack::Util::response_cb($res, sub { \& my $res = shift; \& # do something with $res; \& }); .Ve .PP The callback function gets a \s-1PSGI\s0 response as a 3 element array reference, and you can update the reference to implement the post-processing. .PP .Vb 3 \& package Plack::Middleware::Always500; \& use parent qw(Plack::Middleware); \& use Plack::Util; \& \& sub call { \& my($self, $env) = @_; \& my $res = $self\->app\->($env); \& Plack::Util::response_cb($res, sub { \& my $res = shift; \& $res\->[0] = 500; \& return; \& }); \& } .Ve .PP In this example, the callback gets the \f(CW$res\fR and updates its first element (status code) to 500. Using \f(CW\*(C`response_cb\*(C'\fR makes sure that this works with the delayed response too. .PP You're not required (and not recommended either) to return a new array reference \- they will be simply ignored. You're suggested to explicitly return, unless you fiddle with the content filter callback (see below). .PP Similarly, note that you have to keep the \f(CW$res\fR reference when you swap the entire response. .PP .Vb 5 \& Plack::Util::response_cb($res, sub { \& my $res = shift; \& $res = [ $new_status, $new_headers, $new_body ]; # THIS DOES NOT WORK \& return; \& }); .Ve .PP This does not work, since assigning a new anonymous array to \f(CW$res\fR doesn't update the original \s-1PSGI\s0 response value. You should instead do: .PP .Vb 5 \& Plack::Util::response_cb($res, sub { \& my $res = shift; \& @$res = ($new_status, $new_headers, $new_body); # THIS WORKS \& return; \& }); .Ve .PP The third element of the \s-1PSGI\s0 response array ref is a body, and it could be either an arrayref or IO::Handle\-ish object. The application could also make use of the \f(CW$writer\fR object if \f(CW\*(C`psgi.streaming\*(C'\fR is in effect. Dealing with these variants is again really painful, and \&\f(CW\*(C`response_cb\*(C'\fR can take care of that too, by allowing you to return a content filter as a code reference. .PP .Vb 10 \& # replace all "Foo" in content body with "Bar" \& Plack::Util::response_cb($res, sub { \& my $res = shift; \& return sub { \& my $chunk = shift; \& return unless defined $chunk; \& $chunk =~ s/Foo/Bar/g; \& return $chunk; \& } \& }); .Ve .PP The callback takes one argument \f(CW$chunk\fR and your callback is expected to return the updated chunk. If the given \f(CW$chunk\fR is undef, it means the stream has reached the end, so your callback should also return undef, or return the final chunk and return undef when called next time. .SH "SEE ALSO" .IX Header "SEE ALSO" Plack Plack::Builder Plack::Component