Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Support psgi.streaming

  • Loading branch information...
commit 599f1cd203beb4905ab483cba88a03d22a1f08df 1 parent b613b79
Tatsuhiko Miyagawa authored
Showing with 101 additions and 13 deletions.
  1. +24 −13 lib/Perlbal/Plugin/PSGI.pm
  2. +77 −0 t/perlbal.t
37 lib/Perlbal/Plugin/PSGI.pm
View
@@ -33,6 +33,7 @@ sub handle_request {
'psgi.run_once' => Plack::Util::FALSE,
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => Plack::Util::FALSE,
+ 'psgi.streaming' => Plack::Util::TRUE,
REMOTE_ADDR => $pb->{peer_ip},
SERVER_NAME => (split /:/, $svc->{listen})[0],
SERVER_PORT => (split /:/, $svc->{listen})[1],
@@ -47,20 +48,30 @@ sub handle_request {
open my $input, "<", $buf_ref;
$env->{'psgi.input'} = $input;
- my $res = Plack::Util::run_app $app, $env;
-
- $pb->write("HTTP/1.0 $res->[0] @{[ HTTP::Status::status_message($res->[0]) ]}\015\012");
- while (my($k, $v) = splice @{$res->[1]}, 0, 2) {
- $pb->write("$k: $v\015\012");
- }
- $pb->write("\015\012");
+ my $responder = sub {
+ my $res = shift;
+
+ my $buf = "HTTP/1.0 $res->[0] @{[ HTTP::Status::status_message($res->[0]) ]}\015\012";
+ while (my($k, $v) = splice @{$res->[1]}, 0, 2) {
+ $buf .="$k: $v\015\012";
+ }
+ $buf .= "\015\012";
+ $pb->write($buf);
+
+ if (!defined $res->[2]) {
+ return Plack::Util::inline_object
+ write => sub { $pb->write(@_) },
+ close => sub { $pb->http_response_sent };
+ } elsif (Plack::Util::is_real_fh($res->[2])) {
+ $pb->reproxy_fh($res->[2], -s $res->[2]);
+ } else {
+ Plack::Util::foreach($res->[2], sub { $pb->write(@_) });
+ $pb->write(sub { $pb->http_response_sent });
+ }
+ };
- if (Plack::Util::is_real_fh($res->[2])) {
- $pb->reproxy_fh($res->[2], -s $res->[2]);
- } else {
- Plack::Util::foreach($res->[2], sub { $pb->write(@_) });
- $pb->write(sub { $pb->http_response_sent });
- }
+ my $res = Plack::Util::run_app $app, $env;
+ ref $res eq 'CODE' ? $res->($responder) : $responder->($res);
}
sub handle_psgi_app_command {
77 t/perlbal.t
View
@@ -0,0 +1,77 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::Requires qw(Perlbal);
+use Plack;
+use Test::TCP;
+use LWP::UserAgent;
+use FindBin;
+use Plack::Test::Suite;
+
+
+Plack::Test::Suite->run_server_tests(\&run_perlbal);
+done_testing();
+
+sub run_perlbal {
+ my $port = shift;
+
+ chomp(my $perlbal_bin = `which perlbal`);
+
+ plan skip_all => 'perlbal not found in PATH'
+ unless $perlbal_bin && -x $perlbal_bin;
+
+ my $tmpdir = File::Temp::tempdir( CLEANUP => 1 );
+
+ write_file("$tmpdir/app.psgi", _render_psgi());
+ write_file("$tmpdir/perlbal.conf", _render_conf($tmpdir, $port, "$tmpdir/app.psgi"));
+
+ my $pid = open my $perlbal, "$perlbal_bin -c $tmpdir/perlbal.conf |"
+ or die "Unable to spawn perlbal: $!";
+
+ $SIG{TERM} = sub {
+ kill 'INT', $pid;
+ close $perlbal;
+ exit;
+ };
+
+ sleep 60; # waiting tests.
+ die "server timeout";
+}
+
+sub write_file {
+ my($path, $content) = @_;
+
+ open my $out, ">", $path or die "$path: $!";
+ print $out $content;
+}
+
+sub _render_psgi {
+ return <<'EOF';
+use lib "lib";
+use Plack::Test::Suite;
+
+Plack::Test::Suite->test_app_handler;
+EOF
+}
+
+sub _render_conf {
+ my ($tmpdir, $port, $psgi_path) = @_;
+ <<"END";
+LOAD PSGI
+
+CREATE SERVICE psgi
+ SET listen = 127.0.0.1:$port
+ SET role = web_server
+ SET plugins = psgi
+ PSGI_APP = $psgi_path
+ENABLE psgi
+
+# always good to keep an internal management port open:
+CREATE SERVICE mgmt
+ SET role = management
+ SET listen = 127.0.0.1:60000
+ENABLE mgmt
+
+
+END
+}
Please sign in to comment.
Something went wrong with that request. Please try again.