view release on metacpan or search on metacpan
examples/fatpacked.plackup view on Meta::CPAN
use URI::Escape ();
use Plack::Util;
use Try::Tiny;
my $TRUE = (1 == 1);
my $FALSE = !$TRUE;
sub req_to_psgi {
my $req = shift;
unless (try { $req->isa('HTTP::Request') }) {
Carp::croak("Request is not HTTP::Request: $req");
}
# from HTTP::Request::AsCGI
my $host = $req->header('Host');
my $uri = $req->uri->clone;
$uri->scheme('http') unless $uri->scheme;
$uri->host('localhost') unless $uri->host;
$uri->port(80) unless $uri->port;
$uri->host_port($host) unless !$host || ( $host eq $uri->host_port );
my $input;
my $content = $req->content;
if (ref $content eq 'CODE') {
examples/fatpacked.plackup view on Meta::CPAN
my $o = Plack::Util::inline_object
write => sub { push @$body, @_ },
close => $convert_resp;
return $o;
}
$convert_resp->();
}
sub HTTP::Request::to_psgi {
req_to_psgi(@_);
}
sub HTTP::Response::from_psgi {
my $class = shift;
res_from_psgi(@_);
}
package
HTTP::Message::PSGI::ChunkedInput;
examples/fatpacked.plackup view on Meta::CPAN
sub close { }
package HTTP::Message::PSGI;
1;
__END__
=head1 NAME
HTTP::Message::PSGI - Converts HTTP::Request and HTTP::Response from/to PSGI env and response
=head1 SYNOPSIS
use HTTP::Message::PSGI;
# $req is HTTP::Request, $res is HTTP::Response
my $env = req_to_psgi($req);
my $res = res_from_psgi([ $status, $headers, $body ]);
# Adds methods to HTTP::Request/Response class as well
my $env = $req->to_psgi;
my $res = HTTP::Response->from_psgi([ $status, $headers, $body ]);
=head1 DESCRIPTION
HTTP::Message::PSGI gives you convenient methods to convert an L<HTTP::Request>
object to a PSGI env hash and convert a PSGI response arrayref to
a L<HTTP::Response> object.
If you want the other way around, see L<Plack::Request> and
L<Plack::Response>.
=head1 METHODS
=over 4
=item req_to_psgi
my $env = req_to_psgi($req [, $key => $val ... ]);
Converts a L<HTTP::Request> object into a PSGI env hash reference.
=item HTTP::Request::to_psgi
my $env = $req->to_psgi;
Same as C<req_to_psgi> but an instance method in L<HTTP::Request>.
=item res_from_psgi
my $res = res_from_psgi([ $status, $headers, $body ]);
Creates a L<HTTP::Response> object from a PSGI response array ref.
=item HTTP::Response->from_psgi
my $res = HTTP::Response->from_psgi([ $status, $headers, $body ]);
examples/fatpacked.plackup view on Meta::CPAN
Same as C<res_from_psgi>, but is a class method in L<HTTP::Response>.
=back
=head1 AUTHOR
Tatsuhiko Miyagawa
=head1 SEE ALSO
L<HTTP::Request::AsCGI> L<HTTP::Message> L<Plack::Test>
=cut
HTTP_MESSAGE_PSGI
$fatpacked{"HTTP/Server/PSGI.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'HTTP_SERVER_PSGI';
package HTTP::Server::PSGI;
use strict;
use warnings;
examples/fatpacked.plackup view on Meta::CPAN
L<Plack::Request> gives you a nice wrapper API around PSGI C<$env>
hash to get headers, cookies and query parameters much like
L<Apache::Request> in mod_perl.
L<Plack::Response> does the same to construct the response array
reference.
=head2 Plack::Test
L<Plack::Test> is a unified interface to test your PSGI application
using standard L<HTTP::Request> and L<HTTP::Response> pair with simple
callbacks.
=head2 Plack::Test::Suite
L<Plack::Test::Suite> is a test suite to test a new PSGI server backend.
=head1 CONTRIBUTING
=head2 Patches and Bug Fixes
examples/fatpacked.plackup view on Meta::CPAN
return $res;
}
1;
__END__
=head1 NAME
Plack::LWPish - HTTP::Request/Response compatible interface with HTTP::Tiny backend
=head1 SYNOPSIS
use Plack::LWPish;
my $request = HTTP::Request->new(GET => 'http://perl.com/');
my $ua = Plack::LWPish->new;
my $res = $ua->request($request); # returns HTTP::Response
=head1 DESCRIPTION
This module is an adapter object that implements one method,
C<request> that acts like L<LWP::UserAgent>'s request method
i.e. takes HTTP::Request object and returns HTTP::Response object.
This module is used solely inside L<Plack::Test::Suite> and
L<Plack::Test::Server>, and you are recommended to take a look at
L<HTTP::Thin> if you would like to use this outside Plack.
=head1 AUTHOR
Tatsuhiko Miyagawa
=head1 SEE ALSO
examples/fatpacked.plackup view on Meta::CPAN
=head1 AUTHORS
Tatsuhiko Miyagawa
Kazuhiro Osawa
Tokuhiro Matsuno
=head1 SEE ALSO
L<Plack::Response> L<HTTP::Request>, L<Catalyst::Request>
=head1 LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
PLACK_REQUEST
$fatpacked{"Plack/Request/Upload.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PLACK_REQUEST_UPLOAD';
examples/fatpacked.plackup view on Meta::CPAN
__END__
=head1 NAME
Plack::Test - Test PSGI applications with various backends
=head1 SYNOPSIS
use Plack::Test;
use HTTP::Request::Common;
# Simple OO interface
my $app = sub { return [ 200, [], [ "Hello" ] ] };
my $test = Plack::Test->create($app);
my $res = $test->request(GET "/");
is $res->content, "Hello";
# traditional - named params
test_psgi
app => sub {
my $env = shift;
return [ 200, [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ],
},
client => sub {
my $cb = shift;
my $req = HTTP::Request->new(GET => "http://localhost/hello");
my $res = $cb->($req);
like $res->content, qr/Hello World/;
};
# positional params (app, client)
my $app = sub { return [ 200, [], [ "Hello" ] ] };
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->(GET "/");
is $res->content, "Hello";
};
=head1 DESCRIPTION
Plack::Test is a unified interface to test PSGI applications using
L<HTTP::Request> and L<HTTP::Response> objects. It also allows you to run PSGI
applications in various ways. The default backend is C<Plack::Test::MockHTTP>,
but you may also use any L<Plack::Handler> implementation to run live HTTP
requests against a web server.
=head1 METHODS
=over 4
=item create
$test = Plack::Test->create($app, %options);
creates an instance of Plack::Test implementation class. C<$app> has
to be a valid PSGI application code reference.
=item request
$res = $test->request($request);
takes an HTTP::Request object, runs it through the PSGI application to
test and returns an HTTP::Response object.
=back
=head1 FUNCTIONS
Plack::Test also provides a functional interface that takes two
callbacks, each of which represents PSGI application and HTTP client
code that tests the application.
=over 4
=item test_psgi
test_psgi $app, $client;
test_psgi app => $app, client => $client;
Runs the client test code C<$client> against a PSGI application
C<$app>. The client callback gets one argument C<$cb>, a
callback that accepts an C<HTTP::Request> object and returns an
C<HTTP::Response> object.
Use L<HTTP::Request::Common> to import shortcuts for creating requests for
C<GET>, C<POST>, C<DELETE>, and C<PUT> operations.
For your convenience, the C<HTTP::Request> given to the callback automatically
uses the HTTP protocol and the localhost (I<127.0.0.1> by default), so the
following code just works:
use HTTP::Request::Common;
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->(GET "/hello");
};
Note that however, it is not a good idea to pass an arbitrary
(i.e. user-input) string to C<GET> or even C<<
HTTP::Request->new >> by assuming that it always represents a path,
because:
my $req = GET "//foo/bar";
would represent a request for a URL that has no scheme, has a hostname
I<foo> and a path I</bar>, instead of a path I<//foo/bar> which you
might actually want.
=back
examples/fatpacked.plackup view on Meta::CPAN
Specify the L<Plack::Test> backend using the environment
variable C<PLACK_TEST_IMPL> or C<$Plack::Test::Impl> package variable.
The available values for the backend are:
=over 4
=item MockHTTP
(Default) Creates a PSGI env hash out of HTTP::Request object, runs
the PSGI application in-process and returns HTTP::Response.
=item Server
Runs one of Plack::Handler backends (C<Standalone> by default) and
sends live HTTP requests to test.
=item ExternalServer
Runs tests against an external server specified in the
examples/fatpacked.plackup view on Meta::CPAN
=cut
PLACK_TEST
$fatpacked{"Plack/Test/MockHTTP.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PLACK_TEST_MOCKHTTP';
package Plack::Test::MockHTTP;
use strict;
use warnings;
use Carp;
use HTTP::Request;
use HTTP::Response;
use HTTP::Message::PSGI;
use Try::Tiny;
sub new {
my($class, $app) = @_;
bless { app => $app }, $class;
}
sub request {
examples/fatpacked.plackup view on Meta::CPAN
__END__
=head1 NAME
Plack::Test::MockHTTP - Run mocked HTTP tests through PSGI applications
=head1 DESCRIPTION
Plack::Test::MockHTTP is a utility to run PSGI application given
HTTP::Request objects and return HTTP::Response object out of PSGI
application response. See L<Plack::Test> how to use this module.
=head1 AUTHOR
Tatsuhiko Miyagawa
=head1 SEE ALSO
L<Plack::Test>
=cut
PLACK_TEST_MOCKHTTP
$fatpacked{"Plack/Test/Server.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PLACK_TEST_SERVER';
package Plack::Test::Server;
use strict;
use warnings;
use Carp;
use HTTP::Request;
use HTTP::Response;
use Test::TCP;
use Plack::Loader;
use Plack::LWPish;
sub new {
my($class, $app, %args) = @_;
my $host = $args{host} || '127.0.0.1';
my $server = Test::TCP->new(
examples/fatpacked.plackup view on Meta::CPAN
=cut
PLACK_TEST_SERVER
$fatpacked{"Plack/Test/Suite.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PLACK_TEST_SUITE';
package Plack::Test::Suite;
use strict;
use warnings;
use Digest::MD5;
use File::ShareDir;
use HTTP::Request;
use HTTP::Request::Common;
use Test::More;
use Test::TCP;
use Plack::Loader;
use Plack::Middleware::Lint;
use Plack::Util;
use Plack::Request;
use Try::Tiny;
use Plack::LWPish;
my $share_dir = try { File::ShareDir::dist_dir('Plack') } || 'share';
examples/fatpacked.plackup view on Meta::CPAN
],
[ 'Hello, ' . $body ],
];
},
],
[
'big POST',
sub {
my $cb = shift;
my $chunk = "abcdefgh" x 12000;
my $req = HTTP::Request->new(POST => "http://127.0.0.1/");
$req->content_length(length $chunk);
$req->content_type('application/octet-stream');
$req->content($chunk);
my $res = $cb->($req);
is $res->code, 200;
is $res->message, 'OK';
is $res->header('Client-Content-Length'), length $chunk;
is length $res->content, length $chunk;
is Digest::MD5::md5_hex($res->content), Digest::MD5::md5_hex($chunk);
examples/fatpacked.plackup view on Meta::CPAN
my $env = shift;
open my $io, '>', \my $error;
$env->{'psgi.errors'} = $io;
die "Throwing an exception from app handler. Server shouldn't crash.";
},
],
[
'multi headers (request)',
sub {
my $cb = shift;
my $req = HTTP::Request->new(
GET => "http://127.0.0.1/",
);
$req->push_header(Foo => "bar");
$req->push_header(Foo => "baz");
my $res = $cb->($req);
like($res->content, qr/^bar,\s*baz$/);
},
sub {
my $env = shift;
return [
200,
[ 'Content-Type' => 'text/plain', ],
[ $env->{HTTP_FOO} ]
];
},
],
[
'multi headers (response)',
sub {
my $cb = shift;
my $res = $cb->(HTTP::Request->new(GET => "http://127.0.0.1/"));
my $foo = $res->header('X-Foo');
like $foo, qr/foo,\s*bar,\s*baz/;
},
sub {
my $env = shift;
return [
200,
[ 'Content-Type' => 'text/plain', 'X-Foo', 'foo', 'X-Foo', 'bar, baz' ],
[ 'hi' ]
];
},
],
[
'Do not set $env->{COOKIE}',
sub {
my $cb = shift;
my $req = HTTP::Request->new(
GET => "http://127.0.0.1/",
);
$req->push_header(Cookie => "foo=bar");
my $res = $cb->($req);
is($res->header('X-Cookie'), 0);
is $res->content, 'foo=bar';
},
sub {
my $env = shift;
return [
examples/fatpacked.plackup view on Meta::CPAN
is $res->content, 'Not Found';
},
sub {
return [ 404, [ "Content-Type", "text/plain" ], [ "Not Found" ] ];
},
],
[
'request->input seekable',
sub {
my $cb = shift;
my $req = HTTP::Request->new(POST => "http://127.0.0.1/");
$req->content("body");
$req->content_type('text/plain');
$req->content_length(4);
my $res = $cb->($req);
is $res->content, 'body';
},
sub {
my $req = Plack::Request->new(shift);
return [ 200, [ "Content-Type", "text/plain" ], [ $req->content ] ];
},
examples/fatpacked.plackup view on Meta::CPAN
},
],
[
'handle Authorization header',
sub {
my $cb = shift;
SKIP: {
skip "Authorization header is unsupported under CGI", 4 if ($ENV{PLACK_TEST_HANDLER} || "") eq "CGI";
{
my $req = HTTP::Request->new(
GET => "http://127.0.0.1/",
);
$req->push_header(Authorization => 'Basic XXXX');
my $res = $cb->($req);
is $res->header('X-AUTHORIZATION'), 1;
is $res->content, 'Basic XXXX';
};
{
my $req = HTTP::Request->new(
GET => "http://127.0.0.1/",
);
my $res = $cb->($req);
is $res->header('X-AUTHORIZATION'), 0;
is $res->content, 'no_auth';
};
};
},
sub {
my $env = shift;