Skip to content

Loading…

Close wrapped cgi's STDIN so the process won't hang #238

Merged
merged 1 commit into from

2 participants

@rwstauner

Found child process of executed WrapCGI hanging waiting for more STDIN.
Explicitly closing the handle after writing seems to resolve this.

@rwstauner rwstauner Close wrapped cgi's STDIN so the process won't hang
Found child process of executed WrapCGI hanging waiting for more STDIN.
Explicitly closing the handle after writing seems to resolve this.
2667cdc
@rwstauner

Ran into this issue again on a new install.
Any thoughts on this?

@rwstauner

saw your tweet.
bumping.

@miyagawa miyagawa merged commit b695d4b into plack:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 28, 2011
  1. @rwstauner

    Close wrapped cgi's STDIN so the process won't hang

    rwstauner committed
    Found child process of executed WrapCGI hanging waiting for more STDIN.
    Explicitly closing the handle after writing seems to resolve this.
Showing with 43 additions and 0 deletions.
  1. +2 −0 lib/Plack/App/WrapCGI.pm
  2. +41 −0 t/Plack-Middleware/wrapcgi_exec.t
View
2 lib/Plack/App/WrapCGI.pm
@@ -54,6 +54,8 @@ sub prepare_app {
my $fh = $env->{'psgi.input'};
<$fh>;
});
+ # close STDIN so child will stop waiting
+ close $stdinw;
my $res = '';
while (waitpid($pid, WNOHANG) <= 0) {
View
41 t/Plack-Middleware/wrapcgi_exec.t
@@ -60,5 +60,46 @@ print \$q->header, "Hello " x 10000;
undef $tmp;
}
+# test that wrapped cgi doesn't wait indefinitely for STDIN
+{
+ my $tmp = File::Temp->new(CLEANUP => 1);
+ print $tmp <<"...";
+#!$^X
+print "Content-type: text/plain\\n\\nYou said: ";
+local \$/;
+print <STDIN>;
+...
+ close $tmp;
+
+ chmod(oct("0700"), $tmp->filename) or die "Cannot chmod";
+
+ my $app_exec = Plack::App::WrapCGI->new(script => "$tmp", execute => 1)->to_app;
+ test_psgi app => $app_exec, client => sub {
+ my $cb = shift;
+
+ eval {
+ # without the fix $res->content seems to be "alarm\n" which still fails
+ local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
+ alarm(10);
+ my $res = $cb->(GET "http://localhost/?name=foo");
+ alarm(0);
+ is $res->code, 200;
+ is $res->content, "You said: ";
+
+ alarm(10);
+ $res = $cb->(POST "http://localhost/", Content => "doing things\nthe hard way");
+ alarm(0);
+ is $res->code, 200;
+ is $res->content, "You said: doing things\nthe hard way";
+ };
+ if ( $@ ) {
+ die unless $@ eq "alarm\n"; # propagate unexpected errors
+ ok 0, "request timed out waiting for STDIN";
+ }
+ };
+
+ undef $tmp;
+};
+
done_testing;
Something went wrong with that request. Please try again.