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 "to_app" method that would return the
38       PSGI code reference) to do the actual work. You can use "$self->app" to
39       call the original (wrapped) application.
40
41       Your middleware object is created at a 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 "wrap" method to wrap your application with a middleware:
50
51         use Plack::Middleware::Foo;
52
53         my $app = sub { ... };
54         $app = Plack::Middleware::Foo->wrap($app, %options);
55         $app = Plack::Middleware::Bar->wrap($app, %options);
56

RESPONSE CALLBACK

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

SEE ALSO

153       Plack Plack::Builder Plack::Component
154
155
156
157perl v5.12.3                      2011-06-22              Plack::Middleware(3)
Impressum