Skip to content

Commit

Permalink
Debugging made explicit. Added PSGI mode, and a test for it.
Browse files Browse the repository at this point in the history
  • Loading branch information
supernovus committed Sep 13, 2011
1 parent ab50f0a commit 7b86ab9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 25 deletions.
18 changes: 18 additions & 0 deletions PSGI-test.p6
@@ -0,0 +1,18 @@
#!/usr/bin/env perl6

BEGIN { @*INC.push: './lib'; }

use SCGI;

my $scgi = SCGI.new( :port(8118), :!strict, :PSGI, :debug );

my $handler = sub (%env) {
my $name = %env<QUERY_STRING> || 'World';
my $status = '200';
my @headers = [ 'Content-Type' => 'text/plain' ];
my @body = [ "Hello $name\n"; ];
return [ $status, @headers, @body ];
}

$scgi.handle: $handler;

26 changes: 15 additions & 11 deletions README
Expand Up @@ -8,11 +8,16 @@ Perl 6 HTTP::Daemon library.

It offers a bit of candy coating compared to the Perl 5 version.

It also offers an optional (but recommended) PSGI interface.

The environment contains three special keys:

Request.Body is the request body (usually from an HTTP POST.)
Request.Object is a reference to the individual request object.
Request.SCGI is a reference to the SCGI object itself.
SCGI.Body is the request body (usually from an HTTP POST.)
SCGI.Object is a reference to the individual request object.
SCGI.SCGI is a reference to the SCGI object itself.

If you use the PSGI setting, the standard PSGI variables will be added
to the environment too.

Also, you don't need to create your own IO::Socket::INET object.
Just pass an 'addr' and 'port' attribute to the new() declaration and it'll
Expand All @@ -23,24 +28,23 @@ documentation, there is a convenience method called 'handle' that does
the heavy lifting for you:



use SCGI;

my $scgi = SCGI.new( :addr<localhost>, :port(8080) );
my $scgi = SCGI.new( :addr<localhost>, :port(8080), :PSGI );

my $handler = sub (%env) {
my $name = %env<QUERY_STRING> // 'world';
my $response = "Content-Type: text/plain\n\n";
$response ~= "Hello $name\n";
return $response;
my $status = '200';
my @headers = [ 'Content-Type' => 'text/plain' ];
my @body = [ "Hello $name\n" ];
return [ $status, @headers, @body ];
}

$scgi.handle: $handler;



The output of the handler will be sent as the SCGI response,
so make it a valid CGI response.
If you are not using the PSGI interface, the output of the handler will be
sent as the SCGI response, so make sure it is a valid CGI response!

** Apache configuration:

Expand Down
2 changes: 1 addition & 1 deletion SCGI-test.p6
Expand Up @@ -4,7 +4,7 @@ BEGIN { @*INC.push: './lib'; }

use SCGI;

my $scgi = SCGI.new( :port(8118), :!strict );
my $scgi = SCGI.new( :port(8118) );

my $handler = sub (%env) {
my $name = %env<QUERY_STRING> || 'World';
Expand Down
64 changes: 51 additions & 13 deletions lib/SCGI.pm
Expand Up @@ -7,6 +7,7 @@ class SCGI::Request {
has $.body is rw;
has $.request is rw;
has $!closed is rw = 0;
has $.debug = False;

method err (
$message,
Expand All @@ -26,9 +27,11 @@ class SCGI::Request {

method parse {
$.request = $.connection.get();#recv();
$*ERR.say: "Receieved request: $.request";
if $.debug { $*ERR.say: "Receieved request: $.request"; }
if $.request ~~ / ^ (\d+) \: / {
$*ERR.say: "A proper request was received, parsing into an ENV";
if $.debug {
$*ERR.say: "A proper request was received, parsing into an ENV";
}
my $length = +$0;
my $offset = $0.Str.chars + 1;
my $env_string = $.request.substr($offset, $length);
Expand Down Expand Up @@ -81,29 +84,64 @@ class SCGI {
has $.requestkey = 'SCGI.Request';
has $.scgikey = 'SCGI.Object';

has $.PSGI = False; ## Set to true to use PSGI mode.

has $.debug = False; ## Set to true to debug stuff.

has $.strict = True;

method accept () {
$*ERR.say: "Waiting for connection.";
if ($.debug) {
$*ERR.say: "Waiting for connection.";
}
my $connection = self.socket.accept() or return;
$*ERR.say: "connection family is "~$connection.family;
$*ERR.say: "connection proto is "~$connection.proto;
$*ERR.say: "connection type is "~$connection.type;
SCGI::Request.new( :connection($connection), :strict($.strict) );
if ($.debug) {
$*ERR.say: "connection family is "~$connection.family;
$*ERR.say: "connection proto is "~$connection.proto;
$*ERR.say: "connection type is "~$connection.type;
}
SCGI::Request.new( :connection($connection), :$.strict, :$.debug );
}

method handle (&closure) {
$*ERR.say: "socket family is "~$.socket.family;
$*ERR.say: "socket proto is "~$.socket.proto;
$*ERR.say: "socket type is "~$.socket.type;
if ($.debug) {
$*ERR.say: "socket family is "~$.socket.family;
$*ERR.say: "socket proto is "~$.socket.proto;
$*ERR.say: "socket type is "~$.socket.type;
}
$*ERR.say: "[{time}] SCGI is ready and waiting.";
while (my $request = self.accept) {
$*ERR.say: "Doing the loop";
if ($.debug) { $*ERR.say: "Doing the loop"; }
if $request.parse {
my %env = $request.env;
%env{$.requestkey} = $request;
%env{$.scgikey} = self;
%env{$.bodykey} = $request.body;
$request.connection.send(closure(%env));
%env{$.bodykey} = $request.body;
if ($.PSGI)
{
%env<psgi.version> = [1,0];
%env<psgi.url_scheme> = 'http'; ## FIXME: detect this.
%env<psgi.multithread> = False;
%env<psgi.multiprocess> = False;
%env<psgi.input> = $request.body; ## ??
%env<psgi.errors> = $*ERR; ## Allow override?
%env<psgi.run_once> = False;
%env<psgi.nonblocking> = False; ## Allow when NBIO.
%env<psgi.streaming> = False; ## Eventually?
}
my $return = closure(%env);
my $output;
if ($.PSGI)
{
my $headers = "Status: "~$return[0]~"\n";
for @($return[1]) -> $header {
$headers ~= $header.key ~ ": " ~ $header.value ~ "\n";
}
my $body = $return[2].join("\n");
$output = "$headers\n$body";
}
else { $output = $return; }
$request.connection.send($output);
$request.close;
}
}
Expand Down

0 comments on commit 7b86ab9

Please sign in to comment.