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
|
package Plack::Handler::CGI;
use strict;
use warnings;
use IO::Handle;
sub new { bless {}, shift }
sub run {
my ($self, $app) = @_;
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,
};
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} = '';
}
if ($env->{SCRIPT_NAME} eq '/') {
$env->{SCRIPT_NAME} = '';
$env->{PATH_INFO} = '/' . $env->{PATH_INFO};
}
my $res = $app->($env);
if (ref $res eq 'ARRAY') {
$self->_handle_response($res);
}
elsif (ref $res eq 'CODE') {
$res->(sub {
$self->_handle_response($_[0]);
});
}
else {
die "Bad response $res";
}
}
sub _handle_response {
my ($self, $res) = @_;
*STDOUT->autoflush(1);
my $hdrs;
$hdrs = "Status: $res->[0]\015\012";
my $headers = $res->[1];
while (my ($k, $v) = splice(@$headers, 0, 2)) {
$hdrs .= "$k: $v\015\012";
}
$hdrs .= "\015\012";
print STDOUT $hdrs;
my $body = $res->[2];
my $cb = sub { print STDOUT $_[0] };
# inline Plack::Util::foreach here
if (ref $body eq 'ARRAY') {
for my $line (@$body) {
$cb->($line) if length $line;
}
}
elsif (defined $body) {
local $/ = \65536 unless ref $/;
while (defined(my $line = $body->getline)) {
$cb->($line) if length $line;
}
$body->close;
}
else {
return Plack::Handler::CGI::Writer->new;
}
}
package Plack::Handler::CGI::Writer;
sub new { bless \do { my $x }, $_[0] }
sub write { print STDOUT $_[1] }
sub close { }
package Plack::Handler::CGI;
1;
__END__
=head1 NAME
Plack::Handler::CGI - CGI handler for Plack
=head1 SYNOPSIS
Want to run PSGI application as a CGI script? Rename .psgi to .cgi and
change the shebang line like:
#!/usr/bin/env plackup
# rest of the file can be the same as other .psgi file
You can alternatively create a .cgi file that contains something like:
#!/usr/bin/perl
use Plack::Loader;
my $app = Plack::Util::load_psgi("/path/to/app.psgi");
Plack::Loader->auto->run($app);
This will auto-recognize the CGI environment variable to load this class.
If you really want to explicitly load the CGI handler, you can. For instance
you might do this when you want to embed a PSGI application server built into
CGI-compatible perl-based web server:
use Plack::Handler::CGI;
Plack::Handler::CGI->new->run($app);
=head1 DESCRIPTION
This is a handler module to run any PSGI application as a CGI script.
=head1 SEE ALSO
L<Plack>
=cut
|