1Plack::Middleware(3)  User Contributed Perl Documentation Plack::Middleware(3)
2
3
4

NAME

6       Plack::Middleware - Base class for easy-to-use PSGI middleware
7

SYNOPSIS

9         package Plack::Middleware::Foo;
10         use parent qw( Plack::Middleware );
11
12         sub call {
13             my($self, $env) = @_;
14             # Do something with $env
15
16             # $self->app is the original app
17             my $res = $self->app->($env);
18
19             # Do something with $res
20             return $res;
21         }
22
23         # then in app.psgi
24         use Plack::Builder;
25
26         my $app = sub { ... } # as usual
27
28         builder {
29             enable "Plack::Middleware::Foo";
30             enable "Plack::Middleware::Bar", %options;
31             $app;
32         };
33

DESCRIPTION

35       Plack::Middleware is a utility base class to write PSGI middleware. All
36       you have to do is to inherit from Plack::Middleware and then implement
37       the callback "call" method (or the "to_app" method that would return
38       the PSGI code reference) to do the actual work. You can use
39       "$self->app" to call the original (wrapped) application.
40
41       Your middleware object is created at the PSGI application compile time
42       and is persistent during the web server life cycle (unless it is a non-
43       persistent environment such as CGI), so you should never set or cache
44       per-request data like $env in your middleware object. See also "OBJECT
45       LIFECYCLE" in Plack::Component.
46
47       See Plack::Builder how to actually enable middleware in your .psgi
48       application file using the DSL. If you do not like our builder DSL, you
49       can also use the "wrap" method to wrap your application with a
50       middleware:
51
52         use Plack::Middleware::Foo;
53
54         my $app = sub { ... };
55         $app = Plack::Middleware::Foo->wrap($app, %options);
56         $app = Plack::Middleware::Bar->wrap($app, %options);
57

RESPONSE CALLBACK

59       The typical middleware is written like this:
60
61         package Plack::Middleware::Something;
62         use parent qw(Plack::Middleware);
63
64         sub call {
65             my($self, $env) = @_;
66             # pre-processing $env
67             my $res = $self->app->($env);
68             # post-processing $res
69             return $res;
70         }
71
72       The tricky thing about post-processing the response is that it could
73       either be an immediate 3 element array ref, or a code reference that
74       implements the delayed (streaming) interface.
75
76       Dealing with these two types of response in each piece of middleware is
77       pointless, so you're recommended to use the "response_cb" wrapper
78       function in Plack::Util when implementing a post processing middleware.
79
80         sub call {
81             my($self, $env) = @_;
82             # pre-processing $env
83             my $res = $self->app->($env);
84
85             return Plack::Util::response_cb($res, sub {
86                 my $res = shift;
87                 # do something with $res;
88             });
89         }
90
91       The callback function gets a response as an array reference, and you
92       can update the reference to implement the post-processing. In the
93       normal case, this arrayref will have three elements (as described by
94       the PSGI spec), but will have only two elements when using a $writer as
95       described below.
96
97         package Plack::Middleware::Always500;
98         use parent qw(Plack::Middleware);
99         use Plack::Util;
100
101         sub call {
102             my($self, $env) = @_;
103             my $res  = $self->app->($env);
104             return Plack::Util::response_cb($res, sub {
105                 my $res = shift;
106                 $res->[0] = 500;
107                 return;
108             });
109         }
110
111       In this example, the callback gets the $res and updates its first
112       element (status code) to 500. Using "response_cb" makes sure that this
113       works with the delayed response too.
114
115       You're not required (and not recommended either) to return a new array
116       reference - they will be simply ignored. You're suggested to explicitly
117       return, unless you fiddle with the content filter callback (see below).
118
119       Similarly, note that you have to keep the $res reference when you swap
120       the entire response.
121
122         Plack::Util::response_cb($res, sub {
123             my $res = shift;
124             $res = [ $new_status, $new_headers, $new_body ]; # THIS DOES NOT WORK
125             return;
126         });
127
128       This does not work, since assigning a new anonymous array to $res
129       doesn't update the original PSGI response value. You should instead do:
130
131         Plack::Util::response_cb($res, sub {
132             my $res = shift;
133             @$res = ($new_status, $new_headers, $new_body); # THIS WORKS
134             return;
135         });
136
137       The third element of the response array ref is a body, and it could be
138       either an arrayref or IO::Handle-ish object. The application could also
139       make use of the $writer object if "psgi.streaming" is in effect, and in
140       this case, the third element will not exist ("@$res == 2"). Dealing
141       with these variants is again really painful, and "response_cb" can take
142       care of that too, by allowing you to return a content filter as a code
143       reference.
144
145         # replace all "Foo" in content body with "Bar"
146         Plack::Util::response_cb($res, sub {
147             my $res = shift;
148             return sub {
149                 my $chunk = shift;
150                 return unless defined $chunk;
151                 $chunk =~ s/Foo/Bar/g;
152                 return $chunk;
153             }
154         });
155
156       The callback takes one argument $chunk and your callback is expected to
157       return the updated chunk. If the given $chunk is undef, it means the
158       stream has reached the end, so your callback should also return undef,
159       or return the final chunk and return undef when called next time.
160

SEE ALSO

162       Plack Plack::Builder Plack::Component
163
164
165
166perl v5.32.0                      2020-12-02              Plack::Middleware(3)
Impressum