This file is indexed.

/usr/share/perl5/Plack/Middleware.pm is in libplack-perl 1.0030-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package Plack::Middleware;
use strict;
use warnings;
use Carp ();
use parent qw(Plack::Component);
use Plack::Util;
use Plack::Util::Accessor qw( app );

sub wrap {
    my($self, $app, @args) = @_;
    if (ref $self) {
        $self->{app} = $app;
    } else {
        $self = $self->new({ app => $app, @args });
    }
    return $self->to_app;
}

1;

__END__

=head1 NAME

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

=head1 SYNOPSIS

  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;
  };

=head1 DESCRIPTION

Plack::Middleware is a utility base class to write PSGI
middleware. All you have to do is to inherit from Plack::Middleware
and then implement the callback C<call> method (or the C<to_app> method
that would return the PSGI code reference) to do the actual work. You
can use C<< $self->app >> to call the original (wrapped) application.

Your middleware object is created at the PSGI application compile time
and is persistent during the web server life cycle (unless it is a
non-persistent environment such as CGI), so you should never set or
cache per-request data like C<$env> in your middleware object. See
also L<Plack::Component/"OBJECT LIFECYCLE">.

See L<Plack::Builder> how to actually enable middleware in your
I<.psgi> application file using the DSL. If you do not like our
builder DSL, you can also use the C<wrap> method to wrap your application
with a middleware:

  use Plack::Middleware::Foo;

  my $app = sub { ... };
  $app = Plack::Middleware::Foo->wrap($app, %options);
  $app = Plack::Middleware::Bar->wrap($app, %options);

=head1 RESPONSE CALLBACK

The typical middleware is written like this:

  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;
  }

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.

Dealing with these two types of response in each piece of middleware
is pointless, so you're recommended to use the C<response_cb> wrapper
function in L<Plack::Util> when implementing a post processing
middleware.

  my $res = $app->($env);
  Plack::Util::response_cb($res, sub {
      my $res = shift;
      # do something with $res;
  });

The callback function gets a PSGI response as a 3 element array
reference, and you can update the reference to implement the post-processing.

  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;
      });
  }

In this example, the callback gets the C<$res> and updates its first
element (status code) to 500. Using C<response_cb> makes sure that
this works with the delayed response too.

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).

Similarly, note that you have to keep the C<$res> reference when you
swap the entire response.

  Plack::Util::response_cb($res, sub {
      my $res = shift;
      $res = [ $new_status, $new_headers, $new_body ]; # THIS DOES NOT WORK
      return;
  });

This does not work, since assigning a new anonymous array to C<$res>
doesn't update the original PSGI response value. You should instead
do:

  Plack::Util::response_cb($res, sub {
      my $res = shift;
      @$res = ($new_status, $new_headers, $new_body); # THIS WORKS
      return;
  });

The third element of the PSGI response array ref is a body, and it could
be either an arrayref or L<IO::Handle>-ish object. The application could
also make use of the C<$writer> object if C<psgi.streaming> is in
effect. Dealing with these variants is again really painful, and
C<response_cb> can take care of that too, by allowing you to return a
content filter as a code reference.

  # 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;
      }
  });

The callback takes one argument C<$chunk> and your callback is
expected to return the updated chunk. If the given C<$chunk> 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.

=head1 SEE ALSO

L<Plack> L<Plack::Builder> L<Plack::Component>

=cut