Container-Builder
view release on metacpan or search on metacpan
examples/fatpacked.plackup view on Meta::CPAN
application code reference.
# Hello.psgi
my $app = sub {
my $env = shift;
# ...
return [ $status, $headers, $body ];
};
If you use a web framework, chances are that they provide a helper
utility to automatically generate these C<.psgi> files for you, such
as:
# MyApp.psgi
use MyApp;
my $app = sub { MyApp->run_psgi(@_) };
It's important that the return value of C<.psgi> file is the code
reference. See C<eg/dot-psgi> directory for more examples of C<.psgi>
files.
=head2 plackup, Plack::Runner
L<plackup> is a command line launcher to run PSGI applications from
command line using L<Plack::Loader> to load PSGI backends. It can be
used to run standalone servers and FastCGI daemon processes. Other
server backends like Apache2 needs a separate configuration but
C<.psgi> application file can still be the same.
If you want to write your own frontend that replaces, or adds
functionalities to L<plackup>, take a look at the L<Plack::Runner> module.
=head2 Plack::Middleware
PSGI middleware is a PSGI application that wraps an existing PSGI
application and plays both side of application and servers. From the
servers the wrapped code reference still looks like and behaves
exactly the same as PSGI applications.
L<Plack::Middleware> gives you an easy way to wrap PSGI applications
with a clean API, and compatibility with L<Plack::Builder> DSL.
=head2 Plack::Builder
L<Plack::Builder> gives you a DSL that you can enable Middleware in
C<.psgi> files to wrap existent PSGI applications.
=head2 Plack::Request, Plack::Response
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
Small patches and bug fixes can be either submitted via nopaste on IRC
L<irc://irc.perl.org/#plack> or L<the github issue
tracker|http://github.com/plack/Plack/issues>. Forking on
L<github|http://github.com/plack/Plack> is another good way if you
intend to make larger fixes.
See also L<http://contributing.appspot.com/plack> when you think this
document is terribly outdated.
=head2 Module Namespaces
Modules added to the Plack:: sub-namespaces should be reasonably generic
components which are useful as building blocks and not just simply using
Plack.
Middleware authors are free to use the Plack::Middleware:: namespace for
their middleware components. Middleware must be written in the pipeline
style such that they can chained together with other middleware components.
The Plack::Middleware:: modules in the core distribution are good examples
of such modules. It is recommended that you inherit from L<Plack::Middleware>
for these types of modules.
Not all middleware components are wrappers, but instead are more like
endpoints in a middleware chain. These types of components should use the
Plack::App:: namespace. Again, look in the core modules to see excellent
examples of these (L<Plack::App::File>, L<Plack::App::Directory>, etc.).
It is recommended that you inherit from L<Plack::Component> for these
types of modules.
B<DO NOT USE> Plack:: namespace to build a new web application or a
framework. It's like naming your application under CGI:: namespace if
it's supposed to run on CGI and that is a really bad choice and
would confuse people badly.
=head1 AUTHOR
Tatsuhiko Miyagawa
=head1 COPYRIGHT
The following copyright notice applies to all the files provided in
this distribution, including binary files, unless explicitly noted
otherwise.
Copyright 2009-2013 Tatsuhiko Miyagawa
=head1 CORE DEVELOPERS
Tatsuhiko Miyagawa (miyagawa)
Tokuhiro Matsuno (tokuhirom)
examples/fatpacked.plackup view on Meta::CPAN
listen via TCP on port on all interfaces (Same as C<< listen => ":$port" >>)
=item leave-umask
Set to 1 to disable setting umask to 0 for socket open
=item nointr
Do not allow the listener to be interrupted by Ctrl+C
=item nproc
Specify a number of processes for FCGI::ProcManager
=item pid
Specify a filename for the pid file
=item manager
Specify either a FCGI::ProcManager subclass, or an actual FCGI::ProcManager-compatible object.
If you do not want a FCGI::ProcManager but instead run in a single process, set this to undef.
use FCGI::ProcManager::Dynamic;
Plack::Handler::FCGI->new(
manager => FCGI::ProcManager::Dynamic->new(...),
);
=item daemonize
Daemonize the process.
=item proc-title
Specify process title
=item keep-stderr
Send psgi.errors to STDERR instead of to the FCGI error stream.
=item backlog
Maximum length of the queue of pending connections, defaults to 100.
=back
=head2 EXTENSIONS
Supported L<PSGI::Extensions>.
=over 4
=item psgix.cleanup
push @{ $env->{'psgix.cleanup.handlers'} }, sub { warn "Did this later" }
if $env->{'psgix.cleanup'};
Supports the C<psgix.cleanup> extension,
in order to use it, just push a callback onto
C<< $env->{'psgix.cleanup.handlers' >>.
These callbacks are run after the C<pm_post_dispatch> hook.
=item psgix.harakiri
$env->{'psgix.harakiri.commit'} = 1
if $env->{'psgix.harakiri'};
If there is a L</manager>, then C<psgix.harakiri> will be enabled
and setting C<< $env->{'psgix.harakiri.commit'} >> to a true value
will cause C<< $manager->pm_exit >> to be called after the
request is finished.
=back
=head2 WEB SERVER CONFIGURATIONS
In all cases, you will want to install L<FCGI> and L<FCGI::ProcManager>.
You may find it most convenient to simply install L<Task::Plack> which
includes both of these.
=head3 nginx
This is an example nginx configuration to run your FCGI daemon on a
Unix domain socket and run it at the server's root URL (/).
http {
server {
listen 3001;
location / {
set $script "";
set $path_info $uri;
fastcgi_pass unix:/tmp/fastcgi.sock;
fastcgi_param SCRIPT_NAME $script;
fastcgi_param PATH_INFO $path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
}
}
}
If you want to host your application in a non-root path, then you
should mangle this configuration to set the path to C<SCRIPT_NAME> and
the rest of the path in C<PATH_INFO>.
See L<https://www.nginx.com/resources/wiki/start/topics/examples/fastcgiexample/> for more details.
=head3 Apache mod_fastcgi
After installing C<mod_fastcgi>, you should add the C<FastCgiExternalServer>
directive to your Apache config:
FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/fcgi.sock
examples/fatpacked.plackup view on Meta::CPAN
$env->{PATH_INFO} = $path;
$env->{QUERY_STRING} = $query;
$env->{REQUEST_METHOD} = 'GET';
$env->{CONTENT_LENGTH} = 0;
$env->{CONTENT_TYPE} = '';
$env->{'psgi.input'} = $null_io;
push @{$env->{'plack.recursive.old_path_info'}}, $old_path_info;
$include ? $self->app->($env) : $self->call($env);
};
}
package Plack::Recursive::ForwardRequest;
use overload q("") => \&as_string, fallback => 1;
sub new {
my($class, $path) = @_;
bless { path => $path }, $class;
}
sub path { $_[0]->{path} }
sub throw {
my($class, @args) = @_;
die $class->new(@args);
}
sub as_string {
my $self = shift;
return "Forwarding to $self->{path}: Your application should be wrapped with Plack::Middleware::Recursive.";
}
package Plack::Middleware::Recursive;
1;
__END__
=head1 NAME
Plack::Middleware::Recursive - Allows PSGI apps to include or forward requests recursively
=head1 SYNOPSIS
# with Builder
enable "Recursive";
# in apps
my $res = $env->{'plack.recursive.include'}->("/new_path");
# Or, use exceptions
my $app = sub {
# ...
Plack::Recursive::ForwardRequest->throw("/new_path");
};
=head1 DESCRIPTION
Plack::Middleware::Recursive allows PSGI applications to recursively
include or forward requests to other paths. Applications can make use
of callbacks stored in C<< $env->{'plack.recursive.include'} >> to
I<include> another path to get the response (whether it's an array ref
or a code ref depending on your application), or throw an exception
Plack::Recursive::ForwardRequest anywhere in the code to I<forward>
the current request (i.e. abort the current and redo the request).
=head1 EXCEPTIONS
This middleware passes through unknown exceptions to the outside
middleware stack, so if you use this middleware with other exception
handlers such as L<Plack::Middleware::StackTrace> or
L<Plack::Middleware::HTTPExceptions>, be sure to wrap this so
L<Plack::Middleware::Recursive> gets as inner as possible.
=head1 AUTHORS
Tatsuhiko Miyagawa
Masahiro Honma
=head1 SEE ALSO
L<Plack> L<Plack::Middleware::HTTPExceptions>
The idea, code and interface are stolen from Rack::Recursive and paste.recursive.
=cut
PLACK_MIDDLEWARE_RECURSIVE
$fatpacked{"Plack/Middleware/Refresh.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PLACK_MIDDLEWARE_REFRESH';
package Plack::Middleware::Refresh;
use strict;
use parent qw(Plack::Middleware);
use Module::Refresh;
use Plack::Util::Accessor qw(last cooldown);
sub prepare_app {
my $self = shift;
$self->cooldown(10) unless defined $self->cooldown;
Module::Refresh->new;
$self->last(time - $self->cooldown);
}
sub call {
my($self, $env) = @_;
if (time > $self->last + $self->cooldown) {
Module::Refresh->refresh;
$self->last(time);
}
$self->app->($env);
}
1;
__END__
examples/fatpacked.plackup view on Meta::CPAN
# 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
=head1 OPTIONS
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
( run in 1.711 second using v1.01-cache-2.11-cpan-140bd7fdf52 )