view release on metacpan or search on metacpan
examples/fatpacked.plackup view on Meta::CPAN
REMOTE_PORT => int( rand(64000) + 1000 ), # not in RFC 3875
REQUEST_URI => $uri->path_query || '/', # not in RFC 3875
REQUEST_METHOD => $req->method,
'psgi.version' => [ 1, 1 ],
'psgi.url_scheme' => $uri->scheme eq 'https' ? 'https' : 'http',
'psgi.input' => $input,
'psgi.errors' => *STDERR,
'psgi.multithread' => $FALSE,
'psgi.multiprocess' => $FALSE,
'psgi.run_once' => $TRUE,
'psgi.streaming' => $TRUE,
'psgi.nonblocking' => $FALSE,
@_,
};
for my $field ( $req->headers->header_field_names ) {
my $key = uc("HTTP_$field");
$key =~ tr/-/_/;
$key =~ s/^HTTP_// if $field =~ /^Content-(Length|Type)$/;
unless ( exists $env->{$key} ) {
examples/fatpacked.plackup view on Meta::CPAN
SERVER_NAME => $self->{host},
SCRIPT_NAME => '',
REMOTE_ADDR => $conn->peerhost,
REMOTE_PORT => $conn->peerport || 0,
'psgi.version' => [ 1, 1 ],
'psgi.errors' => *STDERR,
'psgi.url_scheme' => $self->{ssl} ? 'https' : 'http',
'psgi.run_once' => Plack::Util::FALSE,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.nonblocking' => Plack::Util::FALSE,
'psgix.harakiri' => Plack::Util::TRUE,
'psgix.input.buffered' => Plack::Util::TRUE,
'psgix.io' => $conn,
};
$self->handle_connection($env, $conn, $app);
$conn->close;
last if $env->{'psgix.harakiri.commit'};
}
examples/fatpacked.plackup view on Meta::CPAN
my $env = {
%ENV,
'psgi.version' => [ 1, 1 ],
'psgi.url_scheme' => ($ENV{HTTPS}||'off') =~ /^(?:on|1)$/i ? 'https' : 'http',
'psgi.input' => $r,
'psgi.errors' => *STDERR,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::TRUE,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.nonblocking' => Plack::Util::FALSE,
'psgix.harakiri' => Plack::Util::TRUE,
};
if (defined(my $HTTP_AUTHORIZATION = $r->headers_in->{Authorization})) {
$env->{HTTP_AUTHORIZATION} = $HTTP_AUTHORIZATION;
}
my $vpath = $env->{SCRIPT_NAME} . ($env->{PATH_INFO} || '');
examples/fatpacked.plackup view on Meta::CPAN
my $env = {
%ENV,
'psgi.version' => [ 1, 1 ],
'psgi.url_scheme' => ($ENV{HTTPS}||'off') =~ /^(?:on|1)$/i ? 'https' : 'http',
'psgi.input' => $r,
'psgi.errors' => *STDERR,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::TRUE,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.nonblocking' => Plack::Util::FALSE,
'psgix.harakiri' => Plack::Util::TRUE,
'psgix.cleanup' => Plack::Util::TRUE,
'psgix.cleanup.handlers' => [],
};
if (defined(my $HTTP_AUTHORIZATION = $r->headers_in->{Authorization})) {
$env->{HTTP_AUTHORIZATION} = $HTTP_AUTHORIZATION;
}
examples/fatpacked.plackup view on Meta::CPAN
my $env = {
%ENV,
'psgi.version' => [ 1, 1 ],
'psgi.url_scheme' => ($ENV{HTTPS}||'off') =~ /^(?:on|1)$/i ? 'https' : 'http',
'psgi.input' => *STDIN,
'psgi.errors' => *STDERR,
'psgi.multithread' => 0,
'psgi.multiprocess' => 1,
'psgi.run_once' => 1,
'psgi.streaming' => 1,
'psgi.nonblocking' => 1,
%{ $override_env },
};
delete $env->{HTTP_CONTENT_TYPE};
delete $env->{HTTP_CONTENT_LENGTH};
$env->{'HTTP_COOKIE'} ||= $ENV{COOKIE}; # O'Reilly server bug
if (!exists $env->{PATH_INFO}) {
$env->{PATH_INFO} = '';
examples/fatpacked.plackup view on Meta::CPAN
my $env = {
%env,
'psgi.version' => [1,1],
'psgi.url_scheme' => ($env{HTTPS}||'off') =~ /^(?:on|1)$/i ? 'https' : 'http',
'psgi.input' => $self->{stdin},
'psgi.errors' =>
($self->{keep_stderr} ? \*STDERR : $self->{stderr}),
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => defined $proc_manager,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.nonblocking' => Plack::Util::FALSE,
'psgix.harakiri' => defined $proc_manager,
'psgix.cleanup' => 1,
'psgix.cleanup.handlers' => [],
};
delete $env->{HTTP_CONTENT_TYPE};
delete $env->{HTTP_CONTENT_LENGTH};
# lighttpd munges multiple slashes in PATH_INFO into one. Try recovering it
examples/fatpacked.plackup view on Meta::CPAN
close $read;
waitpid($pid, 0);
return $res;
} else {
# child
close $read;
my $res;
try {
$env->{'psgi.streaming'} = 0;
$res = $self->{builder}->()->($env);
my @body;
Plack::Util::foreach($res->[2], sub { push @body, $_[0] });
$res->[2] = \@body;
} catch {
$env->{'psgi.errors'}->print($_);
$res = [ 500, [ "Content-Type", "text/plain" ], [ "Internal Server Error" ] ];
};
print {$write} Storable::freeze($res);
examples/fatpacked.plackup view on Meta::CPAN
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.
sub call {
my($self, $env) = @_;
# pre-processing $env
my $res = $self->app->($env);
examples/fatpacked.plackup view on Meta::CPAN
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 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, and in this case, the third element will not exist
(C<@$res == 2>). 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;
examples/fatpacked.plackup view on Meta::CPAN
no warnings;
use Carp;
use Plack::Util;
use Plack::Util::Accessor qw(force);
use Scalar::Util qw(weaken);
use parent qw(Plack::Middleware);
sub call {
my ( $self, $env ) = @_;
my $caller_supports_streaming = $env->{'psgi.streaming'};
$env->{'psgi.streaming'} = Plack::Util::TRUE;
my $res = $self->app->($env);
return $res if $caller_supports_streaming && !$self->force;
if ( ref($res) eq 'CODE' ) {
my $ret;
$res->(sub {
my $write = shift;
if ( @$write == 2 ) {
my @body;
examples/fatpacked.plackup view on Meta::CPAN
return $res;
}
}
1;
__END__
=head1 NAME
Plack::Middleware::BufferedStreaming - Enable buffering for non-streaming aware servers
=head1 SYNOPSIS
enable "BufferedStreaming";
=head1 DESCRIPTION
Plack::Middleware::BufferedStreaming is a PSGI middleware component
that wraps the application that uses C<psgi.streaming> interface to
run on the servers that do not support the interface, by buffering the
writer output to a temporary buffer.
This middleware doesn't do anything and bypass the application if the
server supports C<psgi.streaming> interface, unless you set C<force>
option (see below).
=head1 OPTIONS
=over 4
=item force
Force enable this middleware only if the container supports C<psgi.streaming>.
=back
=head1 AUTHOR
Yuval Kogman
Tatsuhiko Miyagawa
=cut
examples/fatpacked.plackup view on Meta::CPAN
enable "JSONP", callback_key => 'jsonp';
=head1 DESCRIPTION
Plack::Middleware::JSONP wraps JSON response, which has Content-Type
value either C<text/javascript> or C<application/json> as a JSONP
response which is specified with the C<callback> query parameter. The
name of the parameter can be set while enabling the middleware.
This middleware only works with a non-streaming response, and doesn't
touch the response otherwise.
=head1 AUTHOR
Tatsuhiko Miyagawa
=head1 SEE ALSO
L<Plack>
examples/fatpacked.plackup view on Meta::CPAN
unless (ref($env->{'psgi.version'}) eq 'ARRAY') {
die("psgi.version should be ArrayRef: $env->{'psgi.version'}");
}
unless (scalar(@{$env->{'psgi.version'}}) == 2) {
die('psgi.version should contain 2 elements, not ', scalar(@{$env->{'psgi.version'}}));
}
unless ($env->{'psgi.url_scheme'} =~ /^https?$/) {
die("psgi.url_scheme should be 'http' or 'https': ", $env->{'psgi.url_scheme'});
}
if ($env->{"psgi.version"}->[1] == 1) { # 1.1
for my $param (qw(streaming nonblocking run_once)) {
unless (exists $env->{"psgi.$param"}) {
die("Missing psgi.$param");
}
}
}
if ($env->{HTTP_CONTENT_TYPE}) {
die('HTTP_CONTENT_TYPE should not exist');
}
if ($env->{HTTP_CONTENT_LENGTH}) {
die('HTTP_CONTENT_LENGTH should not exist');
examples/fatpacked.plackup view on Meta::CPAN
sub is_possibly_fh {
my $fh = shift;
ref $fh eq 'GLOB' &&
*{$fh}{IO} &&
*{$fh}{IO}->can('getline');
}
sub validate_res {
my ($self, $res, $streaming) = @_;
unless (ref($res) eq 'ARRAY' or ref($res) eq 'CODE') {
die("Response should be array ref or code ref: $res");
}
if (ref $res eq 'CODE') {
return $self->response_cb($res, sub { $self->validate_res(@_, 1) });
}
unless (@$res == 3 || ($streaming && @$res == 2)) {
die('Response needs to be 3 element array, or 2 element in streaming');
}
unless ($res->[0] =~ /^\d+$/ && $res->[0] >= 100) {
die("Status code needs to be an integer greater than or equal to 100: $res->[0]");
}
unless (ref $res->[1] eq 'ARRAY') {
die("Headers needs to be an array ref: $res->[1]");
}
examples/fatpacked.plackup view on Meta::CPAN
die("Response headers MUST consist only of letters, digits, _ or - and MUST start with a letter. Header: $key");
}
if ($val =~ /[\000-\037]/) {
die("Response headers MUST NOT contain characters below octal \037. Header: $key. Value: $val");
}
unless (defined $val) {
die("Response headers MUST be a defined string. Header: $key");
}
}
# @$res == 2 is only right in psgi.streaming, and it's already checked.
unless (@$res == 2 ||
ref $res->[2] eq 'ARRAY' ||
Plack::Util::is_real_fh($res->[2]) ||
is_possibly_fh($res->[2]) ||
(blessed($res->[2]) && $res->[2]->can('getline'))) {
die("Body should be an array ref or filehandle: $res->[2]");
}
if (ref $res->[2] eq 'ARRAY' && grep _has_wide_char($_), @{$res->[2]}) {
die("Body must be bytes and should not contain wide characters (UTF-8 strings)");
examples/fatpacked.plackup view on Meta::CPAN
This middleware is enabled by default when you run L<plackup> in the
default I<development> mode.
You're recommended to use this middleware during the development and
use L<Plack::Middleware::HTTPExceptions> in the deployment mode as a
replacement, so that all the exceptions thrown from your application
still get caught and rendered as a 500 error response, rather than
crashing the web server.
Catching errors in streaming response is not supported.
=head2 Stack Trace Module
The L<Devel::StackTrace::WithLexicals> module will be used to capture the stack trace
if the installed version is 0.08 or later. Otherwise L<Devel::StackTrace> is used.
=head2 Performance
Gathering the information for a stack trace via L<Devel::StackTrace> is slow,
and L<Devel::StackTrace::WithLexicals> is significantly slower still.
examples/fatpacked.plackup view on Meta::CPAN
my $res = $cb->(GET "http://127.0.0.1/?name=miyagawa");
return if $res->code == 501;
is $res->code, 200;
is $res->message, 'OK';
is $res->header('content_type'), 'text/plain';
is $res->content, 'Hello, name=miyagawa';
},
sub {
my $env = shift;
$env->{'psgi.streaming'} or return [ 501, ['Content-Type','text/plain'], [] ];
return sub {
my $respond = shift;
$respond->([
200,
[ 'Content-Type' => 'text/plain', ],
[ 'Hello, ' . $env->{QUERY_STRING} ],
]);
}
},
],
[
'coderef streaming',
sub {
my $cb = shift;
my $res = $cb->(GET "http://127.0.0.1/?name=miyagawa");
return if $res->code == 501;
is $res->code, 200;
is $res->message, 'OK';
is $res->header('content_type'), 'text/plain';
is $res->content, 'Hello, name=miyagawa';
},
sub {
my $env = shift;
$env->{'psgi.streaming'} or return [ 501, ['Content-Type','text/plain'], [] ];
return sub {
my $respond = shift;
my $writer = $respond->([
200,
[ 'Content-Type' => 'text/plain', ],
]);
$writer->write("Hello, ");